diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a572b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +!.keep +*.DS_Store +*.swo +*.swp +/.bundle +/.env +/.foreman +/coverage/* +/db/*.sqlite3 +/log/* +/public/system +/public/assets +/tags +/tmp/* diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..b1b25a5 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.2.2 diff --git a/.sample.env b/.sample.env new file mode 100644 index 0000000..69f32de --- /dev/null +++ b/.sample.env @@ -0,0 +1,6 @@ +# http://ddollar.github.com/foreman/ +ASSET_HOST=localhost:3000 +HOST=localhost:3000 +RACK_ENV=development +SECRET_KEY_BASE=development_secret +EXECJS_RUNTIME=Node diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7c1a081 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +before_install: + - "echo '--colour' > ~/.rspec" + - "echo 'gem: --no-document' > ~/.gemrc" + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start +install: + - bin/setup +branches: + only: + - master +cache: + - bundler +language: + - ruby +notifications: + email: false +rvm: + - 2.2.2 +addons: + postgresql: "9.3" +sudo: false diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..95c9ae5 --- /dev/null +++ b/Gemfile @@ -0,0 +1,59 @@ +source "https://rubygems.org" + +ruby "2.2.2" + +gem "airbrake" +gem "autoprefixer-rails" +gem "bourbon", "~> 4.2.0" +gem "coffee-rails", "~> 4.1.0" +gem "delayed_job_active_record" +gem "email_validator" +gem "flutie" +gem "high_voltage" +gem "i18n-tasks" +gem "jquery-rails" +gem "neat", "~> 1.7.0" +gem "newrelic_rpm", ">= 3.9.8" +gem "normalize-rails", "~> 3.0.0" +gem "pg" +gem "rack-canonical-host" +gem "rails", "4.2.1" +gem "recipient_interceptor" +gem "refills" +gem "sass-rails", "~> 5.0" +gem "simple_form" +gem "title" +gem "uglifier" +gem "unicorn" + +group :development do + gem "spring" + gem "spring-commands-rspec" + gem "web-console" +end + +group :development, :test do + gem "awesome_print" + gem "bundler-audit", require: false + gem "byebug" + gem "dotenv-rails" + gem "factory_girl_rails" + gem "pry-rails" + gem "rspec-rails", "~> 3.1.0" +end + +group :test do + gem "capybara-webkit", ">= 1.2.0" + gem "database_cleaner" + gem "formulaic" + gem "launchy" + gem "shoulda-matchers", require: false + gem "simplecov", require: false + gem "timecop" + gem "webmock" +end + +group :staging, :production do + gem "rails_stdout_logging" + gem "rack-timeout" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..1cdfdda --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,315 @@ +GEM + remote: https://rubygems.org/ + specs: + actionmailer (4.2.1) + actionpack (= 4.2.1) + actionview (= 4.2.1) + activejob (= 4.2.1) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 1.0, >= 1.0.5) + actionpack (4.2.1) + actionview (= 4.2.1) + activesupport (= 4.2.1) + rack (~> 1.6) + rack-test (~> 0.6.2) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.1) + actionview (4.2.1) + activesupport (= 4.2.1) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.1) + activejob (4.2.1) + activesupport (= 4.2.1) + globalid (>= 0.3.0) + activemodel (4.2.1) + activesupport (= 4.2.1) + builder (~> 3.1) + activerecord (4.2.1) + activemodel (= 4.2.1) + activesupport (= 4.2.1) + arel (~> 6.0) + activesupport (4.2.1) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.3.8) + airbrake (4.2.1) + builder + multi_json + arel (6.0.0) + autoprefixer-rails (5.2.0) + execjs + json + awesome_print (1.6.1) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + bourbon (4.2.3) + sass (~> 3.4) + thor + builder (3.2.2) + bundler-audit (0.3.1) + bundler (~> 1.2) + thor (~> 0.18) + byebug (5.0.0) + columnize (= 0.9.0) + capybara (2.4.4) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + capybara-webkit (1.5.2) + capybara (>= 2.3.0, < 2.5.0) + json + coderay (1.1.0) + coffee-rails (4.1.0) + coffee-script (>= 2.2.0) + railties (>= 4.0.0, < 5.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.9.1.1) + columnize (0.9.0) + crack (0.4.2) + safe_yaml (~> 1.0.0) + database_cleaner (1.4.1) + debug_inspector (0.0.2) + delayed_job (4.0.6) + activesupport (>= 3.0, < 5.0) + delayed_job_active_record (4.0.3) + activerecord (>= 3.0, < 5.0) + delayed_job (>= 3.0, < 4.1) + diff-lcs (1.2.5) + docile (1.1.5) + dotenv (2.0.1) + dotenv-rails (2.0.1) + dotenv (= 2.0.1) + easy_translate (0.5.0) + json + thread + thread_safe + email_validator (1.6.0) + activemodel + erubis (2.7.0) + execjs (2.5.2) + factory_girl (4.5.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.5.0) + factory_girl (~> 4.5.0) + railties (>= 3.0.0) + flutie (2.0.0) + formulaic (0.2.0) + activesupport + capybara + i18n + globalid (0.3.5) + activesupport (>= 4.1.0) + high_voltage (2.3.0) + highline (1.7.2) + i18n (0.7.0) + i18n-tasks (0.8.3) + activesupport + easy_translate (>= 0.5.0) + erubis + highline + i18n + term-ansicolor + terminal-table + jquery-rails (4.0.3) + rails-dom-testing (~> 1.0) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) + json (1.8.3) + kgio (2.9.3) + launchy (2.4.3) + addressable (~> 2.3) + loofah (2.0.2) + nokogiri (>= 1.5.9) + mail (2.6.3) + mime-types (>= 1.16, < 3) + method_source (0.8.2) + mime-types (2.6.1) + mini_portile (0.6.2) + minitest (5.7.0) + multi_json (1.11.0) + neat (1.7.2) + bourbon (>= 4.0) + sass (>= 3.3) + newrelic_rpm (3.12.0.288) + nokogiri (1.6.6.2) + mini_portile (~> 0.6.0) + normalize-rails (3.0.3) + pg (0.18.2) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-rails (0.3.4) + pry (>= 0.9.10) + rack (1.6.1) + rack-canonical-host (0.1.0) + addressable + rack (~> 1.0) + rack-test (0.6.3) + rack (>= 1.0) + rack-timeout (0.2.4) + rails (4.2.1) + actionmailer (= 4.2.1) + actionpack (= 4.2.1) + actionview (= 4.2.1) + activejob (= 4.2.1) + activemodel (= 4.2.1) + activerecord (= 4.2.1) + activesupport (= 4.2.1) + bundler (>= 1.3.0, < 2.0) + railties (= 4.2.1) + sprockets-rails + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (1.0.6) + activesupport (>= 4.2.0.beta, < 5.0) + nokogiri (~> 1.6.0) + rails-deprecated_sanitizer (>= 1.0.1) + rails-html-sanitizer (1.0.2) + loofah (~> 2.0) + rails_stdout_logging (0.0.3) + railties (4.2.1) + actionpack (= 4.2.1) + activesupport (= 4.2.1) + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + raindrops (0.13.0) + rake (10.4.2) + recipient_interceptor (0.1.2) + mail + refills (0.1.0) + rspec-core (3.1.7) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.1.0) + rspec-mocks (3.1.3) + rspec-support (~> 3.1.0) + rspec-rails (3.1.0) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-support (~> 3.1.0) + rspec-support (3.1.2) + safe_yaml (1.0.4) + sass (3.4.14) + sass-rails (5.0.3) + railties (>= 4.0.0, < 5.0) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (~> 1.1) + shoulda-matchers (2.8.0) + activesupport (>= 3.0.0) + simple_form (3.1.0) + actionpack (~> 4.0) + activemodel (~> 4.0) + simplecov (0.10.0) + docile (~> 1.1.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + slop (3.6.0) + spring (1.3.6) + spring-commands-rspec (1.0.4) + spring (>= 0.9.1) + sprockets (3.2.0) + rack (~> 1.0) + sprockets-rails (2.3.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + sprockets (>= 2.8, < 4.0) + term-ansicolor (1.3.0) + tins (~> 1.0) + terminal-table (1.4.5) + thor (0.19.1) + thread (0.2.0) + thread_safe (0.3.5) + tilt (1.4.1) + timecop (0.7.4) + tins (1.5.2) + title (0.0.5) + i18n + rails (>= 3.1) + tzinfo (1.2.2) + thread_safe (~> 0.1) + uglifier (2.7.1) + execjs (>= 0.3.0) + json (>= 1.8.0) + unicorn (4.9.0) + kgio (~> 2.6) + rack + raindrops (~> 0.7) + web-console (2.1.2) + activemodel (>= 4.0) + binding_of_caller (>= 0.7.2) + railties (>= 4.0) + sprockets-rails (>= 2.0, < 4.0) + webmock (1.21.0) + addressable (>= 2.3.6) + crack (>= 0.3.2) + xpath (2.0.0) + nokogiri (~> 1.3) + +PLATFORMS + ruby + +DEPENDENCIES + airbrake + autoprefixer-rails + awesome_print + bourbon (~> 4.2.0) + bundler-audit + byebug + capybara-webkit (>= 1.2.0) + coffee-rails (~> 4.1.0) + database_cleaner + delayed_job_active_record + dotenv-rails + email_validator + factory_girl_rails + flutie + formulaic + high_voltage + i18n-tasks + jquery-rails + launchy + neat (~> 1.7.0) + newrelic_rpm (>= 3.9.8) + normalize-rails (~> 3.0.0) + pg + pry-rails + rack-canonical-host + rack-timeout + rails (= 4.2.1) + rails_stdout_logging + recipient_interceptor + refills + rspec-rails (~> 3.1.0) + sass-rails (~> 5.0) + shoulda-matchers + simple_form + simplecov + spring + spring-commands-rspec + timecop + title + uglifier + unicorn + web-console + webmock + +BUNDLED WITH + 1.10.3 diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..7934897 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb +worker: bundle exec rake jobs:work diff --git a/README.md b/README.md new file mode 100644 index 0000000..c97d836 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Omnibus + +## Getting Started + +After you have cloned this repo, run this setup script to set up your machine +with the necessary dependencies to run and test this app: + + % ./bin/setup + +It assumes you have a machine equipped with Ruby, Postgres, etc. If not, set up +your machine with [this script]. + +[this script]: https://github.com/thoughtbot/laptop + +After setting up, you can run the application using [foreman]: + + % foreman start + +If you don't have `foreman`, see [Foreman's install instructions][foreman]. It +is [purposefully excluded from the project's `Gemfile`][exclude]. + +[foreman]: https://github.com/ddollar/foreman +[exclude]: https://github.com/ddollar/foreman/pull/437#issuecomment-41110407 + +## Guidelines + +Use the following guides for getting things done, programming well, and +programming in style. + +* [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol) +* [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices) +* [Style](http://github.com/thoughtbot/guides/blob/master/style) + +## Deploying + +If you have previously run the `./bin/setup` script, +you can deploy to staging and production with: + + $ ./bin/deploy staging + $ ./bin/deploy production diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..4a77cd0 --- /dev/null +++ b/Rakefile @@ -0,0 +1,17 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Rails.application.load_tasks +task(:default).clear +task default: [:spec] + +if defined? RSpec + task(:spec).clear + RSpec::Core::RakeTask.new(:spec) do |t| + t.verbose = false + end +end + +task default: "bundler:audit" diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 0000000..646c5ab --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,15 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs +//= require_tree . diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 0000000..e701338 --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,8 @@ +@charset "utf-8"; + +@import "normalize-rails"; +@import "bourbon"; +@import "base/grid-settings"; +@import "neat"; +@import "base/base"; +@import "refills/flashes"; diff --git a/app/assets/stylesheets/base/_base.scss b/app/assets/stylesheets/base/_base.scss new file mode 100644 index 0000000..ddc350d --- /dev/null +++ b/app/assets/stylesheets/base/_base.scss @@ -0,0 +1,15 @@ +// Bitters 1.0.0 +// http://bitters.bourbon.io +// Copyright 2013-2015 thoughtbot, inc. +// MIT License + +@import "variables"; + +// Neat Settings -- uncomment if using Neat -- must be imported before Neat +// @import "grid-settings"; + +@import "buttons"; +@import "forms"; +@import "lists"; +@import "tables"; +@import "typography"; diff --git a/app/assets/stylesheets/base/_buttons.scss b/app/assets/stylesheets/base/_buttons.scss new file mode 100644 index 0000000..f902f60 --- /dev/null +++ b/app/assets/stylesheets/base/_buttons.scss @@ -0,0 +1,31 @@ +#{$all-button-inputs}, +button { + @include appearance(none); + -webkit-font-smoothing: antialiased; + background-color: $action-color; + border-radius: $base-border-radius; + border: none; + color: #fff; + cursor: pointer; + display: inline-block; + font-family: $base-font-family; + font-size: $base-font-size; + font-weight: 600; + line-height: 1; + padding: 0.75em 1em; + text-decoration: none; + user-select: none; + vertical-align: middle; + white-space: nowrap; + + &:hover, + &:focus { + background-color: darken($action-color, 15%); + color: #fff; + } + + &:disabled { + cursor: not-allowed; + opacity: 0.5; + } +} diff --git a/app/assets/stylesheets/base/_forms.scss b/app/assets/stylesheets/base/_forms.scss new file mode 100644 index 0000000..db4a796 --- /dev/null +++ b/app/assets/stylesheets/base/_forms.scss @@ -0,0 +1,78 @@ +fieldset { + background-color: lighten($base-border-color, 10%); + border: $base-border; + margin: 0 0 $small-spacing; + padding: $base-spacing; +} + +input, +label, +select { + display: block; + font-family: $base-font-family; + font-size: $base-font-size; +} + +label { + font-weight: 600; + margin-bottom: $small-spacing / 2; + + &.required::after { + content: "*"; + } + + abbr { + display: none; + } +} + +#{$all-text-inputs}, +select[multiple=multiple], +textarea { + background-color: $base-background-color; + border: $base-border; + border-radius: $base-border-radius; + box-shadow: $form-box-shadow; + box-sizing: border-box; + font-family: $base-font-family; + font-size: $base-font-size; + margin-bottom: $base-spacing / 2; + padding: $base-spacing / 3; + transition: border-color; + width: 100%; + + &:hover { + border-color: darken($base-border-color, 10%); + } + + &:focus { + border-color: $action-color; + box-shadow: $form-box-shadow-focus; + outline: none; + } +} + +textarea { + resize: vertical; +} + +input[type="search"] { + @include appearance(none); +} + +input[type="checkbox"], +input[type="radio"] { + display: inline; + margin-right: $small-spacing / 2; +} + +input[type="file"] { + padding-bottom: $small-spacing; + width: 100%; +} + +select { + margin-bottom: $base-spacing; + max-width: 100%; + width: auto; +} diff --git a/app/assets/stylesheets/base/_grid-settings.scss b/app/assets/stylesheets/base/_grid-settings.scss new file mode 100644 index 0000000..c42bdaf --- /dev/null +++ b/app/assets/stylesheets/base/_grid-settings.scss @@ -0,0 +1,14 @@ +@import "neat-helpers"; // or "../neat/neat-helpers" when not in Rails + +// Neat Overrides +// $column: 90px; +// $gutter: 30px; +// $grid-columns: 12; +// $max-width: em(1088); + +// Neat Breakpoints +$medium-screen: em(640); +$large-screen: em(860); + +$medium-screen-up: new-breakpoint(min-width $medium-screen 4); +$large-screen-up: new-breakpoint(min-width $large-screen 8); diff --git a/app/assets/stylesheets/base/_lists.scss b/app/assets/stylesheets/base/_lists.scss new file mode 100644 index 0000000..c989d90 --- /dev/null +++ b/app/assets/stylesheets/base/_lists.scss @@ -0,0 +1,31 @@ +ul, +ol { + list-style-type: none; + margin: 0; + padding: 0; + + &%default-ul { + list-style-type: disc; + margin-bottom: $small-spacing; + padding-left: $base-spacing; + } + + &%default-ol { + list-style-type: decimal; + margin-bottom: $small-spacing; + padding-left: $base-spacing; + } +} + +dl { + margin-bottom: $small-spacing; + + dt { + font-weight: bold; + margin-top: $small-spacing; + } + + dd { + margin: 0; + } +} diff --git a/app/assets/stylesheets/base/_tables.scss b/app/assets/stylesheets/base/_tables.scss new file mode 100644 index 0000000..8c5cc31 --- /dev/null +++ b/app/assets/stylesheets/base/_tables.scss @@ -0,0 +1,25 @@ +table { + @include font-feature-settings("kern", "liga", "tnum"); + border-collapse: collapse; + margin: $small-spacing 0; + table-layout: fixed; + width: 100%; +} + +th { + border-bottom: 1px solid darken($base-border-color, 15%); + font-weight: 600; + padding: $small-spacing 0; + text-align: left; +} + +td { + border-bottom: $base-border; + padding: $small-spacing 0; +} + +tr, +td, +th { + vertical-align: middle; +} diff --git a/app/assets/stylesheets/base/_typography.scss b/app/assets/stylesheets/base/_typography.scss new file mode 100644 index 0000000..358559c --- /dev/null +++ b/app/assets/stylesheets/base/_typography.scss @@ -0,0 +1,55 @@ +body { + @include font-feature-settings("kern", "liga", "pnum"); + -webkit-font-smoothing: antialiased; + color: $base-font-color; + font-family: $base-font-family; + font-size: $base-font-size; + line-height: $base-line-height; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: $heading-font-family; + font-size: $base-font-size; + line-height: $heading-line-height; + margin: 0 0 $small-spacing; +} + +p { + margin: 0 0 $small-spacing; +} + +a { + color: $action-color; + text-decoration: none; + transition: color 0.1s linear; + + &:active, + &:focus, + &:hover { + color: darken($action-color, 15%); + } + + &:active, + &:focus { + outline: none; + } +} + +hr { + border-bottom: $base-border; + border-left: none; + border-right: none; + border-top: none; + margin: $base-spacing 0; +} + +img, +picture { + margin: 0; + max-width: 100%; +} diff --git a/app/assets/stylesheets/base/_variables.scss b/app/assets/stylesheets/base/_variables.scss new file mode 100644 index 0000000..7594759 --- /dev/null +++ b/app/assets/stylesheets/base/_variables.scss @@ -0,0 +1,35 @@ +// Typography +$base-font-family: $helvetica; +$heading-font-family: $base-font-family; + +// Font Sizes +$base-font-size: 1em; + +// Line height +$base-line-height: 1.5; +$heading-line-height: 1.2; + +// Other Sizes +$base-border-radius: 3px; +$base-spacing: $base-line-height * 1em; +$small-spacing: $base-spacing / 2; +$base-z-index: 0; + +// Colors +$blue: #477dca; +$dark-gray: #333; +$medium-gray: #999; +$light-gray: #ddd; + +// Font Colors +$base-background-color: #fff; +$base-font-color: $dark-gray; +$action-color: $blue; + +// Border +$base-border-color: $light-gray; +$base-border: 1px solid $base-border-color; + +// Forms +$form-box-shadow: inset 0 1px 3px rgba(#000, 0.06); +$form-box-shadow-focus: $form-box-shadow, 0 0 5px adjust-color($action-color, $lightness: -5%, $alpha: -0.3); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..d83690e --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,5 @@ +class ApplicationController < ActionController::Base + # Prevent CSRF attacks by raising an exception. + # For APIs, you may want to use :null_session instead. + protect_from_forgery with: :exception +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/helpers/flashes_helper.rb b/app/helpers/flashes_helper.rb new file mode 100644 index 0000000..bef014f --- /dev/null +++ b/app/helpers/flashes_helper.rb @@ -0,0 +1,5 @@ +module FlashesHelper + def user_facing_flashes + flash.to_hash.slice("alert", "error", "notice", "success") + end +end diff --git a/app/mailers/.keep b/app/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/.keep b/app/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/views/application/_analytics.html.erb b/app/views/application/_analytics.html.erb new file mode 100644 index 0000000..5ae6470 --- /dev/null +++ b/app/views/application/_analytics.html.erb @@ -0,0 +1,7 @@ +<% if ENV["SEGMENT_KEY"] %> + +<% end %> diff --git a/app/views/application/_flashes.html.erb b/app/views/application/_flashes.html.erb new file mode 100644 index 0000000..0849058 --- /dev/null +++ b/app/views/application/_flashes.html.erb @@ -0,0 +1,7 @@ +<% if flash.any? %> +
+ <% user_facing_flashes.each do |key, value| -%> +
<%= value %>
+ <% end -%> +
+<% end %> diff --git a/app/views/application/_javascript.html.erb b/app/views/application/_javascript.html.erb new file mode 100644 index 0000000..a738f79 --- /dev/null +++ b/app/views/application/_javascript.html.erb @@ -0,0 +1,12 @@ +<%= javascript_include_tag :application %> + +<%= yield :javascript %> + +<%= render "analytics" %> + +<% if Rails.env.test? %> + <%= javascript_tag do %> + $.fx.off = true; + $.ajaxSetup({ async: false }); + <% end %> +<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..3e38f12 --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,21 @@ + + + + + + + <%# + Configure default and controller-, and view-specific titles in + config/locales/en.yml. For more see: + https://github.com/calebthompson/title#usage + %> + <%= title %> + <%= stylesheet_link_tag :application, media: "all" %> + <%= csrf_meta_tags %> + + + <%= render "flashes" -%> + <%= yield %> + <%= render "javascript" %> + + diff --git a/app/views/pages/.keep b/app/views/pages/.keep new file mode 100644 index 0000000..e69de29 diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..66e9889 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/delayed_job b/bin/delayed_job new file mode 100755 index 0000000..edf1959 --- /dev/null +++ b/bin/delayed_job @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) +require 'delayed/command' +Delayed::Command.new(ARGV).daemonize diff --git a/bin/deploy b/bin/deploy new file mode 100755 index 0000000..deb2ae9 --- /dev/null +++ b/bin/deploy @@ -0,0 +1,12 @@ +#!/bin/sh + +# Run this script to deploy the app to Heroku. + +set -e + +branch="$(git symbolic-ref HEAD --short)" +target="${1:-staging}" + +git push "$target" "$branch:master" +heroku run rake db:migrate --remote "$target" +heroku restart --remote "$target" diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..5191e69 --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..1724048 --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..2658863 --- /dev/null +++ b/bin/setup @@ -0,0 +1,56 @@ +#!/usr/bin/env sh + +# Set up Rails app. Run this script immediately after cloning the codebase. +# https://github.com/thoughtbot/guides/tree/master/protocol + +# Exit if any subcommand fails +set -e + +# Set up Ruby dependencies via Bundler +gem install bundler --conservative +bundle check || bundle install + +# Set up configurable environment variables +if [ ! -f .env ]; then + cp .sample.env .env +fi + +# Set up database and add any development seed data +bundle exec rake db:setup dev:prime + +# Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv +mkdir -p .git/safe + +# Pick a port for Foreman +if ! grep --quiet --no-messages --fixed-strings 'port' .foreman; then + printf 'port: 8000\n' >> .foreman +fi + +if ! command -v foreman > /dev/null; then + printf 'Foreman is not installed.\n' + printf 'See https://github.com/ddollar/foreman for install instructions.\n' +fi + +# Only if this isn't CI +# if [ -z "$CI" ]; then +# fi + +# Set up the staging and production apps. +if heroku join --app omnibus-staging &> /dev/null; then + git remote add staging git@heroku.com:omnibus-staging.git || true + printf 'You are a collaborator on the "omnibus-staging" Heroku app +' +else + printf 'Ask for access to the "omnibus-staging" Heroku app +' +fi + +if heroku join --app omnibus-production &> /dev/null; then + git remote add production git@heroku.com:omnibus-production.git || true + printf 'You are a collaborator on the "omnibus-production" Heroku app +' +else + printf 'Ask for access to the "omnibus-production" Heroku app +' +fi + diff --git a/browserslist b/browserslist new file mode 100644 index 0000000..1e8f87e --- /dev/null +++ b/browserslist @@ -0,0 +1,4 @@ +Last 2 versions +Explorer >= 9 +iOS >= 7.1 +Android >= 4.4 diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..bd83b25 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..6aadcf8 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,50 @@ +require File.expand_path('../boot', __FILE__) + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_view/railtie" +require "sprockets/railtie" +# require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module Omnibus + class Application < Rails::Application + config.i18n.enforce_available_locales = true + + config.generators do |generate| + generate.helper false + generate.javascript_engine false + generate.request_specs false + generate.routing_specs false + generate.stylesheets false + generate.test_framework :rspec + generate.view_specs false + end + + config.action_controller.action_on_unpermitted_parameters = :raise + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Do not swallow errors in after_commit/after_rollback callbacks. + config.active_record.raise_in_transactional_callbacks = true + + config.active_job.queue_adapter = :delayed_job + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..6b750f0 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..98a1cb4 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,12 @@ +development: &default + adapter: postgresql + database: omnibus_development + encoding: utf8 + host: localhost + min_messages: warning + pool: 2 + timeout: 5000 + +test: + <<: *default + database: omnibus_test diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..ee8d90d --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require File.expand_path('../application', __FILE__) + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..8dc3668 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,44 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = true + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + config.action_view.raise_on_missing_translations = true + + config.action_mailer.default_url_options = { host: "localhost:5000" } +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..9584177 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,92 @@ +require Rails.root.join("config/smtp") +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.static_cache_control = "public, max-age=#{1.year.to_i}" + # Enable deflate / gzip compression of controller-generated responses + config.middleware.use Rack::Deflater + + # Ensure requests are only served from one, canonical host name + config.middleware.use Rack::CanonicalHost, ENV.fetch("HOST") + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + config.action_controller.asset_host = ENV.fetch("ASSET_HOST", ENV.fetch("HOST")) + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = SMTP_SETTINGS + + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + config.action_mailer.default_url_options = { host: ENV.fetch("HOST") } +end +Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i diff --git a/config/environments/staging.rb b/config/environments/staging.rb new file mode 100644 index 0000000..d0e0f88 --- /dev/null +++ b/config/environments/staging.rb @@ -0,0 +1,11 @@ +require_relative "production" + +Mail.register_interceptor( + RecipientInterceptor.new(ENV.fetch("EMAIL_RECIPIENTS")) +) + +Rails.application.configure do + # ... + + config.action_mailer.default_url_options = { host: ENV.fetch("HOST") } +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..793219d --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,46 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure static file server for tests with Cache-Control for performance. + config.serve_static_files = true + config.static_cache_control = 'public, max-age=3600' + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Randomize the order test cases are executed. + config.active_support.test_order = :random + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + config.action_view.raise_on_missing_translations = true + + config.action_mailer.default_url_options = { host: "www.example.com" } + + config.active_job.queue_adapter = :inline +end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml new file mode 100644 index 0000000..5380ae1 --- /dev/null +++ b/config/i18n-tasks.yml @@ -0,0 +1,13 @@ +search: + paths: + - "app/controllers" + - "app/helpers" + - "app/presenters" + - "app/views" + +ignore_unused: + - activerecord.* + - date.* + - simple_form.* + - time.* + - titles.* diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 0000000..13abef8 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,11 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = (ENV["ASSETS_VERSION"] || "1.0") + +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100644 index 0000000..7f70458 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/disable_xml_params.rb b/config/initializers/disable_xml_params.rb new file mode 100644 index 0000000..c24d969 --- /dev/null +++ b/config/initializers/disable_xml_params.rb @@ -0,0 +1,3 @@ +# Protect against injection attacks +# http://www.kb.cert.org/vuls/id/380039 +ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML) diff --git a/config/initializers/errors.rb b/config/initializers/errors.rb new file mode 100644 index 0000000..13c1795 --- /dev/null +++ b/config/initializers/errors.rb @@ -0,0 +1,34 @@ +require "net/http" +require "net/smtp" + +# Example: +# begin +# some http call +# rescue *HTTP_ERRORS => error +# notify_hoptoad error +# end + +HTTP_ERRORS = [ + EOFError, + Errno::ECONNRESET, + Errno::EINVAL, + Net::HTTPBadResponse, + Net::HTTPHeaderSyntaxError, + Net::ProtocolError, + Timeout::Error +] + +SMTP_SERVER_ERRORS = [ + IOError, + Net::SMTPAuthenticationError, + Net::SMTPServerBusy, + Net::SMTPUnknownError, + TimeoutError +] + +SMTP_CLIENT_ERRORS = [ + Net::SMTPFatalError, + Net::SMTPSyntaxError +] + +SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..4a994e1 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..ac033bf --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/json_encoding.rb b/config/initializers/json_encoding.rb new file mode 100644 index 0000000..292542f --- /dev/null +++ b/config/initializers/json_encoding.rb @@ -0,0 +1 @@ +ActiveSupport::JSON::Encoding.time_precision = 0 diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..dc18996 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..9c03570 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.session_store :cookie_store, key: '_omnibus_session' diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb new file mode 100644 index 0000000..d5492e5 --- /dev/null +++ b/config/initializers/simple_form.rb @@ -0,0 +1,166 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + # Wrappers are used by the form builder to generate a + # complete input. You can remove any component from the + # wrapper, change the order or even add your own to the + # stack. The options given below are used to wrap the + # whole input. + config.wrappers :default, class: :input, + hint_class: :field_with_hint, error_class: :field_with_errors do |b| + ## Extensions enabled by default + # Any of these extensions can be disabled for a + # given input by passing: `f.input EXTENSION_NAME => false`. + # You can make any of these extensions optional by + # renaming `b.use` to `b.optional`. + + # Determines whether to use HTML5 (:email, :url, ...) + # and required attributes + b.use :html5 + + # Calculates placeholders automatically from I18n + # You can also pass a string as f.input placeholder: "Placeholder" + b.use :placeholder + + ## Optional extensions + # They are disabled unless you pass `f.input EXTENSION_NAME => true` + # to the input. If so, they will retrieve the values from the model + # if any exists. If you want to enable any of those + # extensions by default, you can change `b.optional` to `b.use`. + + # Calculates maxlength from length validations for string inputs + b.optional :maxlength + + # Calculates pattern from format validations for string inputs + b.optional :pattern + + # Calculates min and max from length validations for numeric inputs + b.optional :min_max + + # Calculates readonly automatically from readonly attributes + b.optional :readonly + + ## Inputs + b.use :label_input + b.use :hint, wrap_with: { tag: :span, class: :hint } + b.use :error, wrap_with: { tag: :span, class: :error } + + ## full_messages_for + # If you want to display the full error message for the attribute, you can + # use the component :full_error, like: + # + # b.use :full_error, wrap_with: { tag: :span, class: :error } + end + + # The default wrapper to be used by the FormBuilder. + config.default_wrapper = :default + + # Define the way to render check boxes / radio buttons with labels. + # Defaults to :nested for bootstrap config. + # inline: input + label + # nested: label > input + config.boolean_style = :nested + + # Default class for buttons + config.button_class = 'btn' + + # Method used to tidy up errors. Specify any Rails Array method. + # :first lists the first message for each field. + # Use :to_sentence to list all errors for each field. + # config.error_method = :first + + # Default tag used for error notification helper. + config.error_notification_tag = :div + + # CSS class to add for error notification helper. + config.error_notification_class = 'error_notification' + + # ID to add for error notification helper. + # config.error_notification_id = nil + + # Series of attempts to detect a default label method for collection. + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] + + # Series of attempts to detect a default value method for collection. + # config.collection_value_methods = [ :id, :to_s ] + + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. + # config.collection_wrapper_tag = nil + + # You can define the class to use on all collection wrappers. Defaulting to none. + # config.collection_wrapper_class = nil + + # You can wrap each item in a collection of radio/check boxes with a tag, + # defaulting to :span. Please note that when using :boolean_style = :nested, + # SimpleForm will force this option to be a label. + # config.item_wrapper_tag = :span + + # You can define a class to use in all item wrappers. Defaulting to none. + # config.item_wrapper_class = nil + + # How the label text should be generated altogether with the required text. + # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" } + + # You can define the class to use on all labels. Default is nil. + # config.label_class = nil + + # You can define the default class to be used on forms. Can be overriden + # with `html: { :class }`. Defaulting to none. + # config.default_form_class = nil + + # You can define which elements should obtain additional classes + # config.generate_additional_classes_for = [:wrapper, :label, :input] + + # Whether attributes are required by default (or not). Default is true. + # config.required_by_default = true + + # Tell browsers whether to use the native HTML5 validations (novalidate form option). + # These validations are enabled in SimpleForm's internal config but disabled by default + # in this configuration, which is recommended due to some quirks from different browsers. + # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations, + # change this configuration to true. + config.browser_validations = false + + # Collection of methods to detect if a file type was given. + # config.file_methods = [ :mounted_as, :file?, :public_filename ] + + # Custom mappings for input types. This should be a hash containing a regexp + # to match as key, and the input type that will be used when the field name + # matches the regexp as value. + # config.input_mappings = { /count/ => :integer } + + # Custom wrappers for input types. This should be a hash containing an input + # type as key and the wrapper that will be used for all inputs with specified type. + # config.wrapper_mappings = { string: :prepend } + + # Namespaces where SimpleForm should look for custom input classes that + # override default inputs. + # config.custom_inputs_namespaces << "CustomInputs" + + # Default priority for time_zone inputs. + # config.time_zone_priority = nil + + # Default priority for country inputs. + # config.country_priority = nil + + # When false, do not use translations for labels. + # config.translate_labels = true + + # Automatically discover new inputs in Rails' autoload path. + # config.inputs_discovery = true + + # Cache SimpleForm inputs discovery + # config.cache_discovery = !Rails.env.development? + + # Default class for inputs + # config.input_class = nil + + # Define the default class of the input wrapper of the boolean input. + config.boolean_label_class = 'checkbox' + + # Defines if the default input wrapper class should be included in radio + # collection wrappers. + # config.include_default_input_wrapper_class = true + + # Defines which i18n scope will be used in Simple Form. + # config.i18n_scope = 'simple_form' +end diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..33725e9 --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..631ab2b --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,19 @@ +en: + date: + formats: + default: + "%m/%d/%Y" + with_weekday: + "%a %m/%d/%y" + + time: + formats: + default: + "%a, %b %-d, %Y at %r" + date: + "%b %-d, %Y" + short: + "%B %d" + + titles: + application: Omnibus diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml new file mode 100644 index 0000000..2374383 --- /dev/null +++ b/config/locales/simple_form.en.yml @@ -0,0 +1,31 @@ +en: + simple_form: + "yes": 'Yes' + "no": 'No' + required: + text: 'required' + mark: '*' + # You can uncomment the line below if you need to overwrite the whole required html. + # When using html, text and mark won't be used. + # html: '*' + error_notification: + default_message: "Please review the problems below:" + # Examples + # labels: + # defaults: + # password: 'Password' + # user: + # new: + # email: 'E-mail to sign in.' + # edit: + # email: 'E-mail.' + # hints: + # defaults: + # username: 'User name to sign in.' + # password: 'No special characters, please.' + # include_blanks: + # defaults: + # age: 'Rather not say' + # prompts: + # defaults: + # age: 'Select your age' diff --git a/config/newrelic.yml b/config/newrelic.yml new file mode 100644 index 0000000..ccf25ca --- /dev/null +++ b/config/newrelic.yml @@ -0,0 +1,34 @@ +common: &default_settings + app_name: "omnibus" + audit_log: + enabled: false + browser_monitoring: + auto_instrument: true + capture_params: false + developer_mode: false + error_collector: + capture_source: true + enabled: true + ignore_errors: "ActionController::RoutingError,Sinatra::NotFound" + license_key: "<%= ENV["NEW_RELIC_LICENSE_KEY"] %>" + log_level: info + monitor_mode: true + transaction_tracer: + enabled: true + record_sql: obfuscated + stack_trace_threshold: 0.500 + transaction_threshold: apdex_f +development: + <<: *default_settings + monitor_mode: false + developer_mode: true +test: + <<: *default_settings + monitor_mode: false +production: + <<: *default_settings + monitor_mode: true +staging: + <<: *default_settings + app_name: "omnibus (Staging)" + monitor_mode: true diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..1daf9a4 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,2 @@ +Rails.application.routes.draw do +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 0000000..0bfb22d --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,14 @@ +default: &default + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> + +development: + <<: *default + +test: + <<: *default + +staging: + <<: *default + +production: + <<: *default diff --git a/config/smtp.rb b/config/smtp.rb new file mode 100644 index 0000000..0440e09 --- /dev/null +++ b/config/smtp.rb @@ -0,0 +1,9 @@ +SMTP_SETTINGS = { + address: ENV.fetch("SMTP_ADDRESS"), # example: "smtp.sendgrid.net" + authentication: :plain, + domain: ENV.fetch("SMTP_DOMAIN"), # example: "heroku.com" + enable_starttls_auto: true, + password: ENV.fetch("SMTP_PASSWORD"), + port: "587", + user_name: ENV.fetch("SMTP_USERNAME") +} diff --git a/config/unicorn.rb b/config/unicorn.rb new file mode 100644 index 0000000..555cf62 --- /dev/null +++ b/config/unicorn.rb @@ -0,0 +1,30 @@ +# https://devcenter.heroku.com/articles/rails-unicorn + +worker_processes (ENV["UNICORN_WORKERS"] || 3).to_i +timeout (ENV["UNICORN_TIMEOUT"] || 15).to_i +preload_app true + +before_fork do |_server, _worker| + Signal.trap "TERM" do + puts "Unicorn master intercepting TERM, sending myself QUIT instead" + Process.kill "QUIT", Process.pid + end + + if defined? ActiveRecord::Base + ActiveRecord::Base.connection.disconnect! + end +end + +after_fork do |_server, _worker| + Signal.trap "TERM" do + puts "Unicorn worker intercepting TERM, waiting for master to send QUIT" + end + + if defined? ActiveRecord::Base + config = ActiveRecord::Base.configurations[Rails.env] || + Rails.application.config.database_configuration[Rails.env] + config["reaping_frequency"] = (ENV["DB_REAPING_FREQUENCY"] || 10).to_i + config["pool"] = (ENV["DB_POOL"] || 2).to_i + ActiveRecord::Base.establish_connection(config) + end +end diff --git a/db/migrate/20150610152841_create_delayed_jobs.rb b/db/migrate/20150610152841_create_delayed_jobs.rb new file mode 100644 index 0000000..27fdcf6 --- /dev/null +++ b/db/migrate/20150610152841_create_delayed_jobs.rb @@ -0,0 +1,22 @@ +class CreateDelayedJobs < ActiveRecord::Migration + def self.up + create_table :delayed_jobs, force: true do |table| + table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue + table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. + table.text :handler, null: false # YAML-encoded string of the object that will do work + table.text :last_error # reason for last failure (See Note below) + table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. + table.datetime :locked_at # Set when a client is working on this object + table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) + table.string :locked_by # Who is working on this object (if locked) + table.string :queue # The name of the queue this job is in + table.timestamps null: true + end + + add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" + end + + def self.down + drop_table :delayed_jobs + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..2c36347 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,35 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20150610152841) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "delayed_jobs", force: :cascade do |t| + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree + +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..4edb1e8 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) +# Mayor.create(name: 'Emanuel', city: cities.first) diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/bundler_audit.rake b/lib/tasks/bundler_audit.rake new file mode 100644 index 0000000..00c1263 --- /dev/null +++ b/lib/tasks/bundler_audit.rake @@ -0,0 +1,12 @@ +if Rails.env.development? || Rails.env.test? + require "bundler/audit/cli" + + namespace :bundler do + desc "Updates the ruby-advisory-db and runs audit" + task :audit do + %w(update check).each do |command| + Bundler::Audit::CLI.start [command] + end + end + end +end diff --git a/lib/tasks/development_seeds.rake b/lib/tasks/development_seeds.rake new file mode 100644 index 0000000..b9a7a2d --- /dev/null +++ b/lib/tasks/development_seeds.rake @@ -0,0 +1,12 @@ +if Rails.env.development? || Rails.env.test? + require "factory_girl" + + namespace :dev do + desc "Seed data for development environment" + task prime: "db:setup" do + include FactoryGirl::Syntax::Methods + + # create(:user, email: "user@example.com", password: "password") + end + end +end diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb new file mode 100644 index 0000000..201a069 --- /dev/null +++ b/lib/templates/erb/scaffold/_form.html.erb @@ -0,0 +1,13 @@ +<%%= simple_form_for(@<%= singular_table_name %>) do |f| %> + <%%= f.error_notification %> + +
+ <%- attributes.each do |attribute| -%> + <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %> + <%- end -%> +
+ +
+ <%%= f.button :submit %> +
+<%% end %> diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..7b93ab6 --- /dev/null +++ b/public/404.html @@ -0,0 +1,69 @@ + + + + + + + The page you were looking for doesn't exist (404) + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000..db2ff83 --- /dev/null +++ b/public/422.html @@ -0,0 +1,69 @@ + + + + + + + The change you wanted was rejected (422) + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..e93b854 --- /dev/null +++ b/public/500.html @@ -0,0 +1,68 @@ + + + + + + + We're sorry, but something went wrong (500) + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..3c9c7c0 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/spec/controllers/.keep b/spec/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/features/.keep b/spec/features/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/helpers/.keep b/spec/helpers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb new file mode 100644 index 0000000..71211b8 --- /dev/null +++ b/spec/i18n_spec.rb @@ -0,0 +1,17 @@ +require 'i18n/tasks' + +describe 'I18n' do + let(:i18n) { I18n::Tasks::BaseTask.new } + let(:missing_keys) { i18n.missing_keys } + let(:unused_keys) { i18n.unused_keys } + + it 'does not have missing keys' do + expect(missing_keys).to be_empty, + "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them" + end + + it 'does not have unused keys' do + expect(unused_keys).to be_empty, + "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them" + end +end diff --git a/spec/lib/.keep b/spec/lib/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..789d2cb --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,23 @@ +ENV["RAILS_ENV"] = "test" + +require File.expand_path("../../config/environment", __FILE__) + +require "rspec/rails" +require "shoulda/matchers" + +Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file } + +module Features + # Extend this module in spec/support/features/*.rb + include Formulaic::Dsl +end + +RSpec.configure do |config| + config.include Features, type: :feature + config.infer_base_class_for_anonymous_controllers = false + config.infer_spec_type_from_file_location! + config.use_transactional_fixtures = false +end + +ActiveRecord::Migration.maintain_test_schema! +Capybara.javascript_driver = :webkit diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..46e4254 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,22 @@ +if ENV.fetch("COVERAGE", false) + require "simplecov" + SimpleCov.start "rails" +end + +require "webmock/rspec" + +# http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.syntax = :expect + end + + config.mock_with :rspec do |mocks| + mocks.syntax = :expect + mocks.verify_partial_doubles = true + end + + config.order = :random +end + +WebMock.disable_net_connect!(allow_localhost: true) diff --git a/spec/support/action_mailer.rb b/spec/support/action_mailer.rb new file mode 100644 index 0000000..b9563a3 --- /dev/null +++ b/spec/support/action_mailer.rb @@ -0,0 +1,5 @@ +RSpec.configure do |config| + config.before(:each) do + ActionMailer::Base.deliveries.clear + end +end diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb new file mode 100644 index 0000000..36dcc88 --- /dev/null +++ b/spec/support/database_cleaner.rb @@ -0,0 +1,21 @@ +RSpec.configure do |config| + config.before(:suite) do + DatabaseCleaner.clean_with(:deletion) + end + + config.before(:each) do + DatabaseCleaner.strategy = :transaction + end + + config.before(:each, js: true) do + DatabaseCleaner.strategy = :deletion + end + + config.before(:each) do + DatabaseCleaner.start + end + + config.after(:each) do + DatabaseCleaner.clean + end +end diff --git a/spec/support/factory_girl.rb b/spec/support/factory_girl.rb new file mode 100644 index 0000000..eec437f --- /dev/null +++ b/spec/support/factory_girl.rb @@ -0,0 +1,3 @@ +RSpec.configure do |config| + config.include FactoryGirl::Syntax::Methods +end diff --git a/spec/support/features/.keep b/spec/support/features/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/i18n.rb b/spec/support/i18n.rb new file mode 100644 index 0000000..3d4094d --- /dev/null +++ b/spec/support/i18n.rb @@ -0,0 +1,3 @@ +RSpec.configure do |config| + config.include AbstractController::Translation +end diff --git a/spec/support/matchers/.keep b/spec/support/matchers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/mixins/.keep b/spec/support/mixins/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/shared_examples/.keep b/spec/support/shared_examples/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep new file mode 100644 index 0000000..e69de29