minimum_viable_product 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/minimum_viable_product/application.js.erb +38 -0
  6. data/app/assets/javascripts/minimum_viable_product/init/controllers.js +23 -0
  7. data/app/assets/stylesheets/minimum_viable_product/application.scss +23 -0
  8. data/app/assets/stylesheets/minimum_viable_product/components/buttons.scss +20 -0
  9. data/app/assets/stylesheets/minimum_viable_product/components/fonts.scss +15 -0
  10. data/app/assets/stylesheets/minimum_viable_product/components/spacing.scss +13 -0
  11. data/app/assets/stylesheets/minimum_viable_product/components/typography.scss +40 -0
  12. data/app/assets/stylesheets/minimum_viable_product/init/_reset.scss +43 -0
  13. data/app/assets/stylesheets/minimum_viable_product/init/layout.scss +42 -0
  14. data/app/assets/stylesheets/minimum_viable_product/layout/basic.scss +6 -0
  15. data/app/assets/stylesheets/minimum_viable_product/layout/carousel.scss +128 -0
  16. data/app/assets/stylesheets/minimum_viable_product/layout/cover.scss +111 -0
  17. data/app/assets/stylesheets/minimum_viable_product/pages/sample.scss +14 -0
  18. data/app/assets/stylesheets/minimum_viable_product/skin/style.scss +8 -0
  19. data/app/controllers/minimum_viable_product/analytics_controller.rb +14 -0
  20. data/app/controllers/minimum_viable_product/concerns/analytics_concern.rb +77 -0
  21. data/app/controllers/minimum_viable_product/concerns/seo_concern.rb +25 -0
  22. data/app/controllers/minimum_viable_product/concerns/session_concern.rb +40 -0
  23. data/app/controllers/minimum_viable_product/controller.rb +11 -0
  24. data/app/controllers/minimum_viable_product/seo_controller.rb +13 -0
  25. data/app/controllers/minimum_viable_product/styleguide_controller.rb +17 -0
  26. data/app/helpers/minimum_viable_product/analytics_helper.rb +4 -0
  27. data/app/helpers/minimum_viable_product/application_helper.rb +15 -0
  28. data/app/helpers/minimum_viable_product/bootstrap_helper.rb +38 -0
  29. data/app/helpers/minimum_viable_product/seo_helper.rb +4 -0
  30. data/app/helpers/minimum_viable_product/styleguide_helper.rb +4 -0
  31. data/app/models/concerns/slugification.rb +16 -0
  32. data/app/views/layouts/minimum_viable_product/_header.html.erb +48 -0
  33. data/app/views/layouts/minimum_viable_product/_instrumentation.html.erb +75 -0
  34. data/app/views/layouts/minimum_viable_product/_meta.html.erb +37 -0
  35. data/app/views/layouts/minimum_viable_product/application.html.erb +24 -0
  36. data/app/views/layouts/minimum_viable_product/basic.html.erb +10 -0
  37. data/app/views/layouts/minimum_viable_product/carousel.html.erb +13 -0
  38. data/app/views/layouts/minimum_viable_product/cover.html.erb +13 -0
  39. data/bin/mvp +68 -0
  40. data/config/initializers/canonical_host.rb +3 -0
  41. data/config/initializers/client_side_validations.rb +20 -0
  42. data/config/initializers/cloudinary.rb +6 -0
  43. data/config/initializers/geocoder.rb +9 -0
  44. data/config/initializers/iteration.rb +33 -0
  45. data/config/initializers/rollbar.rb +59 -0
  46. data/config/initializers/segment.rb +5 -0
  47. data/config/initializers/simple_form.rb +165 -0
  48. data/config/initializers/simple_form_bootstrap.rb +149 -0
  49. data/config/initializers/spoof_ip.rb +33 -0
  50. data/config/initializers/ssl.rb +3 -0
  51. data/config/routes.rb +16 -0
  52. data/lib/minimum_viable_product/engine.rb +20 -0
  53. data/lib/minimum_viable_product/ext/nil.rb +5 -0
  54. data/lib/minimum_viable_product/ext/string.rb +7 -0
  55. data/lib/minimum_viable_product/version.rb +3 -0
  56. data/lib/minimum_viable_product.rb +6 -0
  57. data/lib/tasks/sitemap.rake +42 -0
  58. data/test/dummy/README.rdoc +28 -0
  59. data/test/dummy/Rakefile +6 -0
  60. data/test/dummy/app/assets/javascripts/application.js +13 -0
  61. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/test/dummy/app/controllers/application_controller.rb +5 -0
  63. data/test/dummy/app/helpers/application_helper.rb +2 -0
  64. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  65. data/test/dummy/bin/bundle +3 -0
  66. data/test/dummy/bin/rails +4 -0
  67. data/test/dummy/bin/rake +4 -0
  68. data/test/dummy/bin/setup +29 -0
  69. data/test/dummy/config/application.rb +26 -0
  70. data/test/dummy/config/boot.rb +5 -0
  71. data/test/dummy/config/database.yml +25 -0
  72. data/test/dummy/config/environment.rb +5 -0
  73. data/test/dummy/config/environments/development.rb +41 -0
  74. data/test/dummy/config/environments/production.rb +79 -0
  75. data/test/dummy/config/environments/test.rb +42 -0
  76. data/test/dummy/config/initializers/assets.rb +11 -0
  77. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  78. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  79. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  80. data/test/dummy/config/initializers/inflections.rb +16 -0
  81. data/test/dummy/config/initializers/mime_types.rb +4 -0
  82. data/test/dummy/config/initializers/session_store.rb +3 -0
  83. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  84. data/test/dummy/config/locales/en.yml +23 -0
  85. data/test/dummy/config/routes.rb +4 -0
  86. data/test/dummy/config/secrets.yml +22 -0
  87. data/test/dummy/config.ru +4 -0
  88. data/test/dummy/public/404.html +67 -0
  89. data/test/dummy/public/422.html +67 -0
  90. data/test/dummy/public/500.html +66 -0
  91. data/test/dummy/public/favicon.ico +0 -0
  92. data/test/integration/navigation_test.rb +8 -0
  93. data/test/minimum_viable_product_test.rb +7 -0
  94. data/test/test_helper.rb +21 -0
  95. metadata +595 -0
@@ -0,0 +1,149 @@
1
+ # Use this setup block to configure all options available in SimpleForm.
2
+ SimpleForm.setup do |config|
3
+ config.error_notification_class = 'alert alert-danger'
4
+ config.button_class = 'btn btn-default'
5
+ config.boolean_label_class = nil
6
+
7
+ config.wrappers :vertical_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
8
+ b.use :html5
9
+ b.use :placeholder
10
+ b.optional :maxlength
11
+ b.optional :pattern
12
+ b.optional :min_max
13
+ b.optional :readonly
14
+ b.use :label, class: 'control-label'
15
+
16
+ b.use :input, class: 'form-control'
17
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
18
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
19
+ end
20
+
21
+ config.wrappers :vertical_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
22
+ b.use :html5
23
+ b.use :placeholder
24
+ b.optional :maxlength
25
+ b.optional :readonly
26
+ b.use :label, class: 'control-label'
27
+
28
+ b.use :input
29
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
30
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
31
+ end
32
+
33
+ config.wrappers :vertical_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
34
+ b.use :html5
35
+ b.optional :readonly
36
+
37
+ b.wrapper tag: 'div', class: 'checkbox' do |ba|
38
+ ba.use :label_input
39
+ end
40
+
41
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
42
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
43
+ end
44
+
45
+ config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
46
+ b.use :html5
47
+ b.optional :readonly
48
+ b.use :label, class: 'control-label'
49
+ b.use :input
50
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
51
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
52
+ end
53
+
54
+ config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
55
+ b.use :html5
56
+ b.use :placeholder
57
+ b.optional :maxlength
58
+ b.optional :pattern
59
+ b.optional :min_max
60
+ b.optional :readonly
61
+ b.use :label, class: 'col-sm-3 control-label'
62
+
63
+ b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
64
+ ba.use :input, class: 'form-control'
65
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
66
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
67
+ end
68
+ end
69
+
70
+ config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
71
+ b.use :html5
72
+ b.use :placeholder
73
+ b.optional :maxlength
74
+ b.optional :readonly
75
+ b.use :label, class: 'col-sm-3 control-label'
76
+
77
+ b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
78
+ ba.use :input
79
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
80
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
81
+ end
82
+ end
83
+
84
+ config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
85
+ b.use :html5
86
+ b.optional :readonly
87
+
88
+ b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr|
89
+ wr.wrapper tag: 'div', class: 'checkbox' do |ba|
90
+ ba.use :label_input
91
+ end
92
+
93
+ wr.use :error, wrap_with: { tag: 'span', class: 'help-block' }
94
+ wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
95
+ end
96
+ end
97
+
98
+ config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
99
+ b.use :html5
100
+ b.optional :readonly
101
+
102
+ b.use :label, class: 'col-sm-3 control-label'
103
+
104
+ b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
105
+ ba.use :input
106
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
107
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
108
+ end
109
+ end
110
+
111
+ config.wrappers :inline_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
112
+ b.use :html5
113
+ b.use :placeholder
114
+ b.optional :maxlength
115
+ b.optional :pattern
116
+ b.optional :min_max
117
+ b.optional :readonly
118
+ b.use :label, class: 'sr-only'
119
+
120
+ b.use :input, class: 'form-control'
121
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
122
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
123
+ end
124
+
125
+ config.wrappers :multi_select, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
126
+ b.use :html5
127
+ b.optional :readonly
128
+ b.use :label, class: 'control-label'
129
+ b.wrapper tag: 'div', class: 'form-inline' do |ba|
130
+ ba.use :input, class: 'form-control'
131
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
132
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
133
+ end
134
+ end
135
+ # Wrappers for forms and inputs using the Bootstrap toolkit.
136
+ # Check the Bootstrap docs (http://getbootstrap.com)
137
+ # to learn about the different styles for forms and inputs,
138
+ # buttons and other elements.
139
+ config.default_wrapper = :vertical_form
140
+ config.wrapper_mappings = {
141
+ check_boxes: :vertical_radio_and_checkboxes,
142
+ radio_buttons: :vertical_radio_and_checkboxes,
143
+ file: :vertical_file_input,
144
+ boolean: :vertical_boolean,
145
+ datetime: :multi_select,
146
+ date: :multi_select,
147
+ time: :multi_select
148
+ }
149
+ end
@@ -0,0 +1,33 @@
1
+ if ENV['SPOOF_IP'] =~ /^(true|t|yes|y)$/
2
+ Rails.application.config.middleware.use 'SpoofIpMiddleware', ENV['SPOOF_IP'] # will use whatismyipaddress.com if not set
3
+ end
4
+
5
+ BEGIN {
6
+ class SpoofIpMiddleware
7
+ require 'open-uri'
8
+
9
+ def initialize(app, ip)
10
+ @app = app
11
+ @ip = if /\d{2,3}\.\d{2,3}\.\d{2,3}\.\d{2,3}/.match(ip)
12
+ ip
13
+ else
14
+ f = open('http://whatismyipaddress.com/')
15
+ body = f.read
16
+ /\d{2,3}\.\d{2,3}\.\d{2,3}\.\d{2,3}/i.match(body).to_s
17
+ end
18
+ puts %%
19
+ ############## Spoof IP ################
20
+ # Overriding IP address to #{@ip}
21
+ ########################################
22
+ %
23
+ rescue
24
+ # Service unavailable
25
+ end
26
+
27
+ def call(env)
28
+ env['REMOTE_ADDR'] = env['action_dispatch.remote_ip'] = @ip
29
+ @status, @headers, @response = @app.call(env)
30
+ [@status, @headers, @response]
31
+ end
32
+ end
33
+ }
@@ -0,0 +1,3 @@
1
+ if ENV['FORCE_SSL'].to_b == true
2
+ Rails.application.config.middleware.use Rack::SslEnforcer
3
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,16 @@
1
+ MinimumViableProduct::Engine.routes.draw do
2
+ # mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
3
+
4
+ if Rails.env.development?
5
+ get 'styleguide', to: 'styleguide#index'
6
+ get 'styleguide/bootstrap', to: 'styleguide#bootstrap'
7
+ ['basic','cover','carousel'].each do |layout|
8
+ get "styleguide/layouts/#{layout}", to: "styleguide#layout_#{layout}"
9
+ end
10
+ end
11
+
12
+ get 'robots.txt', to: 'seo#robots', as: :robots
13
+ get '/sitemap.xml.gz', to: redirect("https://#{ENV['AWS_S3_BUCKET']}.s3.amazonaws.com/nailsalons/sitemaps/sitemap.xml.gz"), as: :sitemap
14
+
15
+ get 'analytics/optout', to: 'sessions#optout'
16
+ end
@@ -0,0 +1,20 @@
1
+ require 'bootstrap-sass'
2
+ require 'browserify-rails'
3
+ require 'client_side_validations'
4
+ require 'client_side_validations/simple_form'
5
+ require 'cloudinary'
6
+ require 'font-awesome-sass'
7
+ require 'geocoder'
8
+ require 'hashie'
9
+ require 'jquery-rails'
10
+ require "simple_form"
11
+
12
+ require_relative './ext/nil'
13
+ require_relative './ext/string'
14
+
15
+ module MinimumViableProduct
16
+ class Engine < ::Rails::Engine
17
+ # isolate_namespace MinimumViableProduct
18
+ config.autoload_paths << "#{Rails.root}/lib"
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ class NilClass
2
+ def to_b
3
+ return false
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class String
2
+ def to_b
3
+ return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
4
+ return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i)
5
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module MinimumViableProduct
2
+ VERSION = "0.0.8"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "minimum_viable_product/engine"
2
+
3
+ module MinimumViableProduct
4
+ end
5
+
6
+ MVP = Mvp = MinimumViableProduct
@@ -0,0 +1,42 @@
1
+ require 'fog'
2
+
3
+ namespace :sitemap do
4
+ desc 'Upload the sitemap files to S3'
5
+ task upload: :environment do
6
+ puts "Starting sitemap upload to S3..."
7
+
8
+ connection = Fog::Storage.new({
9
+ :provider => 'AWS',
10
+ :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
11
+ :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
12
+ })
13
+
14
+ directory = connection.directories.get(ENV['AWS_S3_BUCKET'])
15
+
16
+ Dir.entries(File.join(Rails.root, "tmp", "sitemaps")).each do |file_name|
17
+ next if ['.', '..', '.DS_Store'].include? file_name
18
+ path = "__PROJECT_NAME_SLUG__/sitemaps/#{file_name}"
19
+ file = File.new(File.join(Rails.root, "tmp", "sitemaps", file_name))
20
+
21
+ begin
22
+ file = directory.files.create(
23
+ :body => file,
24
+ :key => path,
25
+ :public => true
26
+ )
27
+ # object = bucket.objects[path]
28
+ # object.write(file: file)
29
+ rescue Exception => e
30
+ raise e
31
+ end
32
+ puts "Saved #{file_name} to S3"
33
+ end
34
+ end
35
+
36
+ desc 'Create the sitemap, then upload it to S3 and ping the search engines'
37
+ task worker: :environment do
38
+ Rake::Task["sitemap:create"].invoke
39
+ Rake::Task["sitemap:upload"].invoke
40
+ SitemapGenerator::Sitemap.ping_search_engines(Rails.application.routes.url_helpers.sitemap_url)
41
+ end
42
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
6
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ # path to your application root.
5
+ APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6
+
7
+ Dir.chdir APP_ROOT do
8
+ # This script is a starting point to setup your application.
9
+ # Add necessary setup steps to this file:
10
+
11
+ puts "== Installing dependencies =="
12
+ system "gem install bundler --conservative"
13
+ system "bundle check || bundle install"
14
+
15
+ # puts "\n== Copying sample files =="
16
+ # unless File.exist?("config/database.yml")
17
+ # system "cp config/database.yml.sample config/database.yml"
18
+ # end
19
+
20
+ puts "\n== Preparing database =="
21
+ system "bin/rake db:setup"
22
+
23
+ puts "\n== Removing old logs and tempfiles =="
24
+ system "rm -f log/*"
25
+ system "rm -rf tmp/cache"
26
+
27
+ puts "\n== Restarting application server =="
28
+ system "touch tmp/restart.txt"
29
+ end