diff --git a/.gitignore b/.gitignore index cc90ddb..61d62ed 100644 --- a/.gitignore +++ b/.gitignore @@ -47,10 +47,6 @@ rerun.txt pickle-email-*.html .project -# Ignore Gemfile.lock so that we always get the most up to date gems -# We'll be testing in 'preview' to avoid clashes -Gemfile.lock - # Ignore Redis' dataset snapshot dump.rdb diff --git a/Gemfile b/Gemfile index 1d0c2bd..0fec91c 100644 --- a/Gemfile +++ b/Gemfile @@ -5,58 +5,42 @@ gem 'pg' gem 'rake', '11.1.2' gem 'ruby_dep', '1.3.1' # Lock at 1.3.1 since 1.4 requires ruby 2.5. We should unlock once we upgrade the ruby version on our server -# gem 'bcrypt-ruby', '3.0.0', require: 'bcrypt' -# gem 'bcrypt', '3.1.9' -# gem 'bcrypt', require: :ruby gem 'rack-mini-profiler' gem 'haml' -gem 'nokogiri', '~> 1.6.8.rc2' +gem 'nokogiri' -if Dir.exists?('../lingua_franca') - gem 'lingua_franca', :path => '../lingua_franca' -else - gem 'lingua_franca', :git => 'git://github.com/lingua-franca/lingua_franca.git' -end - -gem 'tzinfo-data' gem 'sass' gem 'sass-rails' - -if Dir.exists?('../bumbleberry') - gem 'bumbleberry', :path => "../bumbleberry" -else - gem 'bumbleberry', :git => 'git://github.com/bumbleberry/bumbleberry.git' -end - -if Dir.exists?('../paypal-express') - gem 'paypal-express', :path => "../paypal-express" -else - gem 'paypal-express', :git => 'git://github.com/bikebike/paypal-express.git' -end - gem 'uglifier', '>= 1.3.0' -gem 'sorcery', '>= 0.8.1' -gem 'oauth2', '~> 0.8.0' +# replace this once these changes are merged in sorcery +gem 'sorcery', git: 'https://github.com/tg90nor/sorcery.git', branch: 'make-facebook-provider-use-json-token-parser' gem 'carrierwave' gem 'carrierwave-imageoptimizer' gem 'mini_magick' -gem 'geocoder' -gem 'paper_trail', '~> 3.0.5' -gem 'sitemap_generator' gem 'activerecord-session_store' -gem 'sass-json-vars' gem 'premailer-rails' -gem 'redcarpet' gem 'sidekiq' gem 'letter_opener' gem 'launchy' -gem 'to_spreadsheet', :git => 'git://github.com/glebm/to_spreadsheet.git' -group :test do - gem 'rspec' - gem 'rspec-rails' -end +# Bike Collectives gems, when developing locally execute: +# bundle config local.bikecollectives_core ../bikecollectives_core +# bundle config local.bumbleberry ../bumbleberry +# bundle config local.lingua_franca ../lingua_franca +# bundle config local.marmara ../marmara +gem 'bikecollectives_core', git: 'https://github.com/bikebike/bikecollectives_core.git', branch: 'master' +gem 'bumbleberry', git: 'https://github.com/bumbleberry/bumbleberry.git', branch: '2017' +gem 'lingua_franca', git: 'https://github.com/lingua-franca/lingua_franca.git', branch: '2017' +gem 'marmara', git: 'https://github.com/lingua-franca/marmara.git', branch: 'master' + +# Bike!Bike! specific stuff +gem 'ianfleeton-paypal-express', require: 'paypal/express' +gem 'geocoder' +gem 'sitemap_generator' +gem 'sass-json-vars' +gem 'redcarpet' +gem 'to_spreadsheet', git: 'https://github.com/glebm/to_spreadsheet.git' group :development do gem 'better_errors' @@ -67,17 +51,23 @@ group :development do gem 'capistrano-rails', '~> 1.1' gem 'capistrano-faster-assets', '~> 1.0' - gem 'eventmachine', :github => 'krzcho/eventmachine', :branch => 'master' - gem 'thin'# , :github => 'krzcho/thin', :branch => 'master' + gem 'eventmachine', git: 'https://github.com/krzcho/eventmachine', :branch => 'master' + gem 'thin' + gem 'rubocop', require: false + gem 'haml-lint', require: false end group :test do + gem 'rspec' + gem 'rspec-rails' gem 'gherkin3', '>= 3.1.0' gem 'cucumber' gem 'cucumber-core' - gem 'cucumber-rails' + gem 'cucumber-rails', require: false + gem 'guard-cucumber' gem 'poltergeist' + gem 'capybara-email' gem 'guard-rspec' gem 'factory_girl_rails' gem 'coveralls', require: false @@ -90,16 +80,22 @@ end group :production, :preview do gem 'rails_12factor' - gem 'daemon-spawn' - gem 'daemons' - +end + +group :production, :preview do platforms :ruby do - gem 'unicorn' + gem 'unicorn', require: false end + + gem 'daemon-spawn' + gem 'daemons' end platforms 'mswin', 'mingw' do + gem 'tzinfo-data' + group :test do gem 'wdm', '>= 0.1.0' + gem 'win32console', require: false end end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..e52b085 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,633 @@ +GIT + remote: https://github.com/glebm/to_spreadsheet.git + revision: 4c08455646dd18de51cc1ec05717fbb240c78a68 + specs: + to_spreadsheet (1.0.6) + axlsx + chronic + nokogiri + rails + responders + +GIT + remote: https://github.com/ianfleeton/paypal-express + revision: 629749621de4c65dd6651649f98410315520fb3d + specs: + paypal-express (0.8.1) + activesupport (>= 2.3) + attr_required (>= 0.0.5) + rest-client + +GIT + remote: https://github.com/krzcho/eventmachine + revision: 651a35ee9df9826e048c3b3721e2c6b415c5a328 + branch: master + specs: + eventmachine (1.2.1) + +GIT + remote: https://github.com/tg90nor/sorcery.git + revision: 79b69a87ce168c47fab76921874aa7e8cb727002 + branch: make-facebook-provider-use-json-token-parser + specs: + sorcery (0.10.3) + bcrypt (~> 3.1) + oauth (~> 0.4, >= 0.4.4) + oauth2 (~> 1.0, >= 0.8.0) + +PATH + remote: ../bikecollectives_core + specs: + bikecollectives_core (0.1.0) + activerecord-session_store + carrierwave + carrierwave-imageoptimizer + haml + launchy + letter_opener + mini_magick + pg + premailer-rails + rails (~> 4.2.0) + redcarpet + sass + sass-json-vars + sass-rails + sidekiq + uglifier (>= 1.3.0) + +PATH + remote: ../bumbleberry + specs: + bumbleberry (0.0.1) + blockspring + cairo + railties + rsvg2 + sass-json-vars + sass-rails + +PATH + remote: ../lingua_franca + specs: + lingua_franca (0.0.1) + diffy + forgery + http_accept_language + i18n + rails (~> 4.2.0.rc2) + rails-i18n + rubyzip + +PATH + remote: ../marmara + specs: + marmara (1.0.2) + css_parser (>= 1.5.0.pre) + +GEM + remote: http://rubygems.org/ + specs: + actionmailer (4.2.0) + actionpack (= 4.2.0) + actionview (= 4.2.0) + activejob (= 4.2.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 1.0, >= 1.0.5) + actionpack (4.2.0) + actionview (= 4.2.0) + activesupport (= 4.2.0) + rack (~> 1.6.0) + rack-test (~> 0.6.2) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.1) + actionview (4.2.0) + activesupport (= 4.2.0) + 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.0) + activesupport (= 4.2.0) + globalid (>= 0.3.0) + activemodel (4.2.0) + activesupport (= 4.2.0) + builder (~> 3.1) + activerecord (4.2.0) + activemodel (= 4.2.0) + activesupport (= 4.2.0) + arel (~> 6.0) + activerecord-session_store (1.0.0) + actionpack (>= 4.0, < 5.1) + activerecord (>= 4.0, < 5.1) + multi_json (~> 1.11, >= 1.11.2) + rack (>= 1.5.2, < 3) + railties (>= 4.0, < 5.1) + activesupport (4.2.0) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + airbrussh (1.1.2) + sshkit (>= 1.6.1, != 1.7.0) + arel (6.0.4) + ast (2.3.0) + attr_required (1.0.1) + axlsx (2.0.1) + htmlentities (~> 4.3.1) + nokogiri (>= 1.4.1) + rubyzip (~> 1.0.0) + bcrypt (3.1.11-x64-mingw32) + bcrypt (3.1.11-x86-mingw32) + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + blockspring (0.1.4) + rest-client (> 1.6.7) + builder (3.2.3) + cairo (1.15.5-x64-mingw32) + pkg-config (>= 1.1.5) + cairo (1.15.5-x86-mingw32) + pkg-config (>= 1.1.5) + callsite (0.0.11) + capistrano (3.8.0) + airbrussh (>= 1.0.0) + i18n + rake (>= 10.0.0) + sshkit (>= 1.9.0) + capistrano-bundler (1.2.0) + capistrano (~> 3.1) + sshkit (~> 1.2) + capistrano-faster-assets (1.0.2) + capistrano (>= 3.1) + capistrano-rails (1.2.3) + capistrano (~> 3.1) + capistrano-bundler (~> 1.1) + capybara (2.13.0) + addressable + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + capybara-email (2.5.0) + capybara (~> 2.4) + mail + carrierwave (1.0.0) + activemodel (>= 4.0.0) + activesupport (>= 4.0.0) + mime-types (>= 1.16) + carrierwave-imageoptimizer (1.4.0) + carrierwave (>= 0.8, < 2.0) + image_optimizer (~> 1.6) + childprocess (0.6.3) + ffi (~> 1.0, >= 1.0.11) + chronic (0.10.2) + cliver (0.3.2) + coderay (1.1.1) + concurrent-ruby (1.0.5) + connection_pool (2.2.1) + coveralls (0.8.20) + json (>= 1.8, < 3) + simplecov (~> 0.14.1) + term-ansicolor (~> 1.3) + thor (~> 0.19.4) + tins (~> 1.6) + crack (0.4.3) + safe_yaml (~> 1.0.0) + css_parser (1.5.0.pre2) + addressable + cucumber (2.4.0) + builder (>= 2.1.2) + cucumber-core (~> 1.5.0) + cucumber-wire (~> 0.0.1) + diff-lcs (>= 1.1.3) + gherkin (~> 4.0) + multi_json (>= 1.7.5, < 2.0) + multi_test (>= 0.1.2) + cucumber-core (1.5.0) + gherkin (~> 4.0) + cucumber-rails (1.4.5) + capybara (>= 1.1.2, < 3) + cucumber (>= 1.3.8, < 4) + mime-types (>= 1.16, < 4) + nokogiri (~> 1.5) + railties (>= 3, < 5.1) + cucumber-wire (0.0.1) + daemon-spawn (0.4.2) + daemons (1.2.4) + database_cleaner (1.5.3) + debug_inspector (0.0.2) + diff-lcs (1.3) + diffy (3.2.0) + docile (1.1.5) + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + erubis (2.7.0) + execjs (2.7.0) + factory_girl (4.8.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) + railties (>= 3.0.0) + faraday (0.11.0) + multipart-post (>= 1.2, < 3) + ffi (1.9.18-x64-mingw32) + ffi (1.9.18-x86-mingw32) + forgery (0.6.0) + formatador (0.2.5) + gdk_pixbuf2 (3.1.1-x64-mingw32) + gio2 (= 3.1.1) + gdk_pixbuf2 (3.1.1-x86-mingw32) + gio2 (= 3.1.1) + geocoder (1.4.3) + gherkin (4.1.1) + gherkin3 (3.1.2) + gio2 (3.1.1-x64-mingw32) + glib2 (= 3.1.1) + gobject-introspection (= 3.1.1) + gio2 (3.1.1-x86-mingw32) + glib2 (= 3.1.1) + gobject-introspection (= 3.1.1) + git-version-bump (0.15.1) + glib2 (3.1.1-x64-mingw32) + cairo (>= 1.12.8) + pkg-config + glib2 (3.1.1-x86-mingw32) + cairo (>= 1.12.8) + pkg-config + globalid (0.3.7) + activesupport (>= 4.1.0) + gobject-introspection (3.1.1-x64-mingw32) + glib2 (= 3.1.1) + gobject-introspection (3.1.1-x86-mingw32) + glib2 (= 3.1.1) + guard (2.14.1) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-cucumber (2.1.2) + cucumber (~> 2.0) + guard-compat (~> 1.0) + nenv (~> 0.1) + guard-rspec (4.7.3) + guard (~> 2.1) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) + haml (4.0.7) + tilt + haml-lint (0.999.999) + haml_lint + haml_lint (0.24.0) + haml (>= 4.0, < 5.1) + rainbow + rake (>= 10, < 13) + rubocop (>= 0.47.0) + sysexits (~> 1.1) + hashdiff (0.3.2) + htmlentities (4.3.4) + http-cookie (1.0.3) + domain_name (~> 0.5) + http_accept_language (2.1.0) + i18n (0.8.1) + image_optimizer (1.7.0) + json (1.8.6) + jwt (1.5.6) + kgio (2.11.0) + launchy (2.4.3) + addressable (~> 2.3) + letter_opener (1.4.1) + launchy (~> 2.2) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + loofah (2.0.3) + nokogiri (>= 1.5.9) + lumberjack (1.0.11) + mail (2.6.4) + mime-types (>= 1.16, < 4) + meta_request (0.4.0) + callsite (~> 0.0, >= 0.0.11) + rack-contrib (~> 1.1) + railties (>= 3.0.0, < 5.1.0) + metaclass (0.0.4) + method_source (0.8.2) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mini_magick (4.7.0) + mini_portile2 (2.1.0) + minitest (5.10.1) + mocha (1.2.1) + metaclass (~> 0.0.1) + multi_json (1.12.1) + multi_test (0.1.2) + multi_xml (0.6.0) + multipart-post (2.0.0) + nenv (0.3.0) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (4.1.0) + netrc (0.11.0) + nokogiri (1.6.8.1-x64-mingw32) + mini_portile2 (~> 2.1.0) + nokogiri (1.6.8.1-x86-mingw32) + mini_portile2 (~> 2.1.0) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) + oauth (0.5.1) + oauth2 (1.3.1) + faraday (>= 0.8, < 0.12) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + pango (3.1.1-x64-mingw32) + cairo (>= 1.14.0) + glib2 (= 3.1.1) + pango (3.1.1-x86-mingw32) + cairo (>= 1.14.0) + glib2 (= 3.1.1) + parser (2.4.0.0) + ast (~> 2.2) + pg (0.20.0-x64-mingw32) + pg (0.20.0-x86-mingw32) + pkg-config (1.1.7) + poltergeist (1.14.0) + capybara (~> 2.1) + cliver (~> 0.3.1) + websocket-driver (>= 0.2.0) + powerpack (0.1.1) + premailer (1.10.2) + addressable + css_parser (>= 1.4.10) + htmlentities (>= 4.0.0) + premailer-rails (1.9.5) + actionmailer (>= 3, < 6) + premailer (~> 1.7, >= 1.7.9) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + public_suffix (2.0.5) + rack (1.6.5) + rack-contrib (1.4.0) + git-version-bump (~> 0.15) + rack (~> 1.4) + rack-mini-profiler (0.10.2) + rack (>= 1.2.0) + rack-protection (1.5.3) + rack + rack-test (0.6.3) + rack (>= 1.0) + rails (4.2.0) + actionmailer (= 4.2.0) + actionpack (= 4.2.0) + actionview (= 4.2.0) + activejob (= 4.2.0) + activemodel (= 4.2.0) + activerecord (= 4.2.0) + activesupport (= 4.2.0) + bundler (>= 1.3.0, < 2.0) + railties (= 4.2.0) + sprockets-rails + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (1.0.8) + activesupport (>= 4.2.0.beta, < 5.0) + nokogiri (~> 1.6) + rails-deprecated_sanitizer (>= 1.0.1) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + rails-i18n (4.0.9) + i18n (~> 0.7) + railties (~> 4.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) + railties (4.2.0) + actionpack (= 4.2.0) + activesupport (= 4.2.0) + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rainbow (2.2.1) + raindrops (0.18.0) + rake (11.1.2) + rb-fsevent (0.9.8) + rb-inotify (0.9.8) + ffi (>= 0.5.0) + redcarpet (3.4.0) + redis (3.3.3) + responders (2.3.0) + railties (>= 4.2.0, < 5.1) + rest-client (2.0.1-x64-mingw32) + ffi (~> 1.9) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) + rest-client (2.0.1-x86-mingw32) + ffi (~> 1.9) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.4) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-rails (3.5.2) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + rsvg2 (3.1.1-x64-mingw32) + cairo (>= 1.12.8) + gdk_pixbuf2 (= 3.1.1) + pango (>= 3.1.1) + rsvg2 (3.1.1-x86-mingw32) + cairo (>= 1.12.8) + gdk_pixbuf2 (= 3.1.1) + pango (>= 3.1.1) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.8.1) + ruby_dep (1.3.1) + rubyzip (1.0.0) + safe_yaml (1.0.4) + sass (3.4.23) + sass-json-vars (0.3.3) + sass (>= 3.1) + sass-rails (5.0.6) + railties (>= 4.0.0, < 6) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) + selenium-webdriver (3.3.0) + childprocess (~> 0.5) + rubyzip (~> 1.0) + websocket (~> 1.0) + shellany (0.0.1) + sidekiq (4.2.10) + concurrent-ruby (~> 1.0) + connection_pool (~> 2.2, >= 2.2.0) + rack-protection (>= 1.5.0) + redis (~> 3.2, >= 3.2.1) + simplecov (0.14.1) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + sitemap_generator (5.3.1) + builder (~> 3.0) + slop (3.6.0) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.0) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + sshkit (1.13.1) + net-scp (>= 1.1.2) + net-ssh (>= 2.8.0) + sysexits (1.2.0) + term-ansicolor (1.5.0) + tins (~> 1.0) + thin (1.7.0) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0, >= 1.0.4) + rack (>= 1, < 3) + thor (0.19.4) + thread_safe (0.3.6) + tilt (2.0.7) + tins (1.13.2) + tzinfo (1.2.3) + thread_safe (~> 0.1) + tzinfo-data (1.2017.2) + tzinfo (>= 1.0.0) + uglifier (3.1.13) + execjs (>= 0.3.0, < 3) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2-x64-mingw32) + unf_ext (0.0.7.2-x86-mingw32) + unicode-display_width (1.1.3) + unicorn (5.3.0) + kgio (~> 2.6) + raindrops (~> 0.7) + wdm (0.1.1) + webmock (2.3.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + websocket (1.2.4) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) + win32console (1.3.2-x86-mingw32) + xpath (2.0.0) + nokogiri (~> 1.3) + +PLATFORMS + x64-mingw32 + x86-mingw32 + +DEPENDENCIES + activerecord-session_store + better_errors + bikecollectives_core! + binding_of_caller + bumbleberry! + capistrano (~> 3.1) + capistrano-faster-assets (~> 1.0) + capistrano-rails (~> 1.1) + capybara-email + carrierwave + carrierwave-imageoptimizer + coveralls + cucumber + cucumber-core + cucumber-rails + daemon-spawn + daemons + database_cleaner + eventmachine! + factory_girl_rails + geocoder + gherkin3 (>= 3.1.0) + guard-cucumber + guard-rspec + haml + haml-lint + launchy + letter_opener + lingua_franca! + marmara! + meta_request + mini_magick + mocha + nokogiri (~> 1.6.8.rc2) + paypal-express! + pg + poltergeist + premailer-rails + rack-mini-profiler + rails (= 4.2.0) + rails_12factor + rake (= 11.1.2) + redcarpet + rspec + rspec-rails + rubocop + ruby_dep (= 1.3.1) + sass + sass-json-vars + sass-rails + selenium-webdriver + sidekiq + simplecov + sitemap_generator + sorcery! + thin + to_spreadsheet! + tzinfo-data + uglifier (>= 1.3.0) + unicorn + wdm (>= 0.1.0) + webmock + win32console + +BUNDLED WITH + 1.14.4 diff --git a/Guardfile b/Guardfile index e6e7c78..e5db626 100644 --- a/Guardfile +++ b/Guardfile @@ -22,3 +22,28 @@ guard :rspec do watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end + +cucumber_options = { + # Below are examples overriding defaults + + # cmd: 'bin/cucumber', + # cmd_additional_args: '--profile guard', + + # all_after_pass: false, + # all_on_start: false, + # keep_failed: false, + # feature_sets: ['features/frontend', 'features/experimental'], + + # run_all: { cmd_additional_args: '--profile guard_all' }, + # focus_on: { 'wip' }, # @wip + # notification: false +} + +guard "cucumber", cucumber_options do + watch(%r{^features/.+\.feature$}) + watch(%r{^features/support/.+$}) { "features" } + + watch(%r{^features/step_definitions/(.+)_steps\.rb$}) do |m| + Dir[File.join("**/#{m[1]}.feature")][0] || "features" + end +end diff --git a/README.md b/README.md index 10a69b3..7ce286e 100644 --- a/README.md +++ b/README.md @@ -150,3 +150,8 @@ On hold until our design team determines a director for our identity. ## Testing Practices ## Our focus will be on integration testing using Capybara. While testing the app records all translations that it finds, whether or not they exist, and which pages that they were found on. + +## Attribution ## + +### Icons ### + diff --git a/Rakefile b/Rakefile index b9a026c..ffec68e 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,8 @@ # 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 'rubygems' +require 'cucumber' +require 'cucumber/rake/task' require File.expand_path('../config/application', __FILE__) @@ -61,3 +64,31 @@ task update_cities_fr: :environment do c.save! end end + +task :i18n do + LinguaFranca.test LinguaFranca::TestModes::RECORD do + Rake::Task[:cucumber].execute + end +end + +task :css do + ENV['CSS_TEST'] = '1' + Rake::Task[:cucumber].execute + ENV['CSS_TEST'] = nil +end + +task :a11y do + ENV['TEST_A11Y'] = '1' + Rake::Task[:cucumber].execute + ENV['TEST_A11Y'] = nil +end + +task "cucumber:debug" do + ENV['TEST_DEBUG'] = '1' + Rake::Task[:cucumber].execute + ENV['TEST_DEBUG'] = nil +end + +Cucumber::Rake::Task.new(:cucumber) do |t| + t.cucumber_opts = "features --format pretty" +end diff --git a/app/assets/images/test-poster.png b/app/assets/images/test-poster.png new file mode 100644 index 0000000..29d20c1 Binary files /dev/null and b/app/assets/images/test-poster.png differ diff --git a/app/assets/javascripts/userfield.js b/app/assets/javascripts/userfield.js index 3ee54d8..593e15a 100644 --- a/app/assets/javascripts/userfield.js +++ b/app/assets/javascripts/userfield.js @@ -21,6 +21,7 @@ var field = fields[i]; var input = field.getElementsByTagName('input')[0]; var name = field.getElementsByClassName('user-name')[0]; + } }, false); })(); diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss index fb851df..d4121c4 100644 --- a/app/assets/stylesheets/_application.scss +++ b/app/assets/stylesheets/_application.scss @@ -1710,17 +1710,17 @@ ul.warnings { a.policy { background-color: $colour-5; - @include _(order, 1); + // @include _(order, 1); } a.about { background-color: $colour-3; - @include _(order, 1); + // @include _(order, 1); } a.conferences { background-color: $colour-2; - @include _(order, 1); + // @include _(order, 1); } form, .register { @@ -1728,7 +1728,8 @@ ul.warnings { } a, form { - width: 33%; + width: 33.333%; + float: left; @include _(flex, 1); } @@ -2948,12 +2949,11 @@ a.logo { .conference-banner { text-align: center; padding: 0; - margin: 0 -1em 2em; - width: auto; + margin: 0; .title { font-size: 5vw; - margin: 1em auto 2em; + margin: 1em auto 0; h1, h2 { margin: 0; @@ -2971,6 +2971,7 @@ a.logo { img { max-width: 100%; + margin-top: 2em; } } @@ -3311,8 +3312,11 @@ body.error-locale-not-available { body { #primary-content { @include _(transition, 'filter 250ms ease-in-out, -webkit-filter 250ms ease-in-out'); - display: -webkit-flex; - flex-direction: column; + + @if capable_of(flexbox, true) { + display: -webkit-flex; + flex-direction: column; + } min-height: 100vh; overflow: hidden; } @@ -4617,6 +4621,7 @@ html[data-ontop] { .nav a { &[class] { width: auto; + float: none; overflow: visible; margin-left: 0.725em; padding: 0.25em 0.5em; diff --git a/app/assets/stylesheets/bumbleberry-settings.json b/app/assets/stylesheets/bumbleberry-settings.json index 0ca48d3..5a67c7c 100644 --- a/app/assets/stylesheets/bumbleberry-settings.json +++ b/app/assets/stylesheets/bumbleberry-settings.json @@ -1,103 +1,105 @@ { - "stylesheets": ["application", "editor"], - "precompile": { - "test": { - "chrome": ["51"] - }, - "development": { - "and_chr": ["56"], - "chrome": ["56"], - "edge": ["13"], - "firefox": ["50"], - "ie": ["11"], - "ios_saf": ["8", "9"] - } + "stylesheets": ["application", "editor", "admin"], + "precompile": { + "test": { + "safari": ["5"], + "chrome": ["55"] }, - "background-color": "#FFFEFE", - "breakpoint-unit": "px", - "unresponsive-width": 1000, - "row-width": 1000, - "total-columns": 12, - "platforms": { - "mobile": { - "range": [0,700] - }, - "desktop": { - "range": [0,0] - } + "development": { + "safari": ["5", "5.1"], + "and_chr": ["57"], + "chrome": ["57"], + "edge": ["13"], + "firefox": ["50"], + "ie": ["11"], + "ios_saf": ["8", "9"] + } + }, + "background-color": "#FFFEFE", + "breakpoint-unit": "px", + "unresponsive-width": 1000, + "row-width": 1000, + "total-columns": 12, + "platforms": { + "mobile": { + "range": [0,700] + }, + "desktop": { + "range": [0,0] + } + }, + "breakpoints": { + "small": { + "range": [0], + "grid": "y", + "offset": "n", + "reset-order": "n" }, - "breakpoints": { - "small": { - "range": [0], - "grid": "y", - "offset": "n", - "reset-order": "n" - }, - "medium": { - "range": [680], - "grid": "y", - "offset": "n", - "reset-order": "n" - }, - "large": { - "range": [1024], - "grid": "y", - "offset": "n", - "reset-order": "n" - }, - "small-only": { - "range": [0,319], - "grid": "n", - "offset": "n", - "reset-order": "n" - }, - "medium-only": { - "range": [320,1023], - "grid": "n", - "offset": "n", - "reset-order": "n" - } + "medium": { + "range": [680], + "grid": "y", + "offset": "n", + "reset-order": "n" }, - "grid-push": [1, 2], - "grid-pull": [1, 2], - "font-loading-method": "http2", - "fonts": { - "primary": { - "name": "Sanchez Light", - "location": "Sanchez", - "svg_id": "wf", - "ttf_type": "ttf", - "fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] - }, - "secondary": { - "name": "AlteHaasGroteskBold", - "location": "AlteHaasGroteskBold", - "svg_id": "alte_haas_groteskbold", - "ttf_type": "ttf", - "fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] - }, - "monospace": { - "name": "NotCourierSans", - "location": "NotCourierSans", - "svg_id": "notcouriersans", - "ttf_type": "ttf", - "fallback": ["Courier New", "monospace"], - "auto_load": "n" - }, - "monospace-bold": { - "name": "NotCourierSans", - "location": "NotCourierSans-Bold", - "svg_id": "notcouriersansbold", - "ttf_type": "ttf", - "fallback": ["Courier New", "monospace"], - "auto_load": "n", - "weight": "bold" - } + "large": { + "range": [1024], + "grid": "y", + "offset": "n", + "reset-order": "n" }, - "sprites": { - "icons": { - "bb-icon-logo": [0, 0, "182px", "149px"], - "bb-icon-logo-text": ["182px", 0, "136px", "149px"] - } + "small-only": { + "range": [0,319], + "grid": "n", + "offset": "n", + "reset-order": "n" + }, + "medium-only": { + "range": [320,1023], + "grid": "n", + "offset": "n", + "reset-order": "n" + } + }, + "grid-push": [1, 2], + "grid-pull": [1, 2], + "font-loading-method": "http2", + "fonts": { + "primary": { + "name": "Sanchez Light", + "location": "Sanchez", + "svg_id": "wf", + "ttf_type": "ttf", + "fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] + }, + "secondary": { + "name": "AlteHaasGroteskBold", + "location": "AlteHaasGroteskBold", + "svg_id": "alte_haas_groteskbold", + "ttf_type": "ttf", + "fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] + }, + "monospace": { + "name": "NotCourierSans", + "location": "NotCourierSans", + "svg_id": "notcouriersans", + "ttf_type": "ttf", + "fallback": ["Courier New", "monospace"], + "auto_load": "n" + }, + "monospace-bold": { + "name": "NotCourierSans", + "location": "NotCourierSans-Bold", + "svg_id": "notcouriersansbold", + "ttf_type": "ttf", + "fallback": ["Courier New", "monospace"], + "auto_load": "n", + "weight": "bold" + } + }, + "sprites": { + "icons": { + "bb-icon-logo": [0, 0, "182px", "149px"], + "bb-icon-logo-text": ["182px", 0, "136px", "149px"] } + } } diff --git a/app/assets/stylesheets/user-mailer.scss b/app/assets/stylesheets/user-mailer.scss index af6e781..b312e63 100644 --- a/app/assets/stylesheets/user-mailer.scss +++ b/app/assets/stylesheets/user-mailer.scss @@ -1,268 +1,268 @@ @import "settings"; body { - width: 100% !important; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - margin: 1em; - padding: 0; + width: 100% !important; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + margin: 1em; + padding: 0; } .ExternalClass { - width: 100%; - line-height: 100%; + width: 100%; + line-height: 100%; - p, span, font, td, div { - line-height: 100%; - } + p, span, font, td, div { + line-height: 100%; + } } #backgroundTable { - margin: 0; - padding: 0; - width: 100% !important; - max-width: 100% !important; - line-height: 100% !important; + margin: 0; + padding: 0; + width: 100% !important; + max-width: 100% !important; + line-height: 100% !important; } img { - outline: none; - text-decoration: none; - -ms-interpolation-mode: bicubic; + outline: none; + text-decoration: none; + -ms-interpolation-mode: bicubic; - a & { - border: none; - } + a & { + border: none; + } } .image_fix { - display: block; - max-width: 100%; + display: block; + max-width: 100%; } a { - color: $colour-1; - - #outlook & { - padding: 0; - } - - &:link { color: $colour-1; } - &:visited { color: $colour-1; } - &:hover { color: $colour-5; } - - @media only screen and (max-device-width: 480px) { - &[href^="tel"], &[href^="sms"] { - text-decoration: none; - color: $black; - pointer-events: none; - cursor: default; - } - - .mobile_link &[href^="tel"], .mobile_link &[href^="sms"] { - text-decoration: default; - color: $colour-1 !important; - pointer-events: auto; - cursor: default; - } - } + color: $colour-1; + + #outlook & { + padding: 0; + } + + &:link { color: $colour-1; } + &:visited { color: $colour-1; } + &:hover { color: $colour-5; } + + @media only screen and (max-device-width: 480px) { + &[href^="tel"], &[href^="sms"] { + text-decoration: none; + color: $black; + pointer-events: none; + cursor: default; + } + + .mobile_link &[href^="tel"], .mobile_link &[href^="sms"] { + text-decoration: default; + color: $colour-1 !important; + pointer-events: auto; + cursor: default; + } + } } p { - color: $black !important; - font-size: 1.5em; + color: $black !important; + font-size: 1.5em; } p, blockquote { - margin: 1em; - line-height: 1.3333em; + margin: 1em; + line-height: 1.3333em; } blockquote { - font-size: 1em; + font-size: 1em; } h1 { - font-size: 2.5em; - line-height: 1.25em; - padding: 1em 0; - - &:first-child { - padding-top: 0; - } + font-size: 2.5em; + line-height: 1.25em; + padding: 1em 0; + + &:first-child { + padding-top: 0; + } } h2 { - font-size: 1.8em; - line-height: 1.25em; - padding-bottom: 1em; + font-size: 1.8em; + line-height: 1.25em; + padding-bottom: 1em; } blockquote { - font-style: italic; - margin-bottom: 2em; - color: #666 !important; - border: 0.1em solid #CCC; - padding: 1em; - border-style: none none solid solid; - background-color: #F8F8F8; + font-style: italic; + margin-bottom: 2em; + color: #666 !important; + border: 0.1em solid #CCC; + padding: 1em; + border-style: none none solid solid; + background-color: #F8F8F8; } h1, h2, h3, h4, h5, h6 { - color: $black !important; - - a { - color: $colour-1 !important; - - &:active { - color: $colour-4 !important; - } - - &:visited { - color: $colour-2 !important; - } - } + color: $black !important; + + a { + color: $colour-1 !important; + + &:active { + color: $colour-4 !important; + } + + &:visited { + color: $colour-2 !important; + } + } } table { - border-collapse: collapse; - max-width: 512px; - min-width: 280px; - mso-table-lspace: 0pt; - mso-table-rspace: 0pt; - - td { - border-collapse: collapse; - } - - th { - text-align: left; - } + border-collapse: collapse; + max-width: 512px; + min-width: 280px; + mso-table-lspace: 0pt; + mso-table-rspace: 0pt; + + td { + border-collapse: collapse; + } + + th { + text-align: left; + } } table#bb_full_width, table#ecxbb_full_width { - &, table { - max-width: none; - width: 100%; - } + &, table { + max-width: none; + width: 100%; + } } .error-report { - width: 100%; - max-width: 100%; - border: 0.15em solid #CCC; - background-color: #EEE; - font-size: 1.25em; - margin-bottom: 2em; - - th { - background-color: #CCC; - } - - td, th { - padding: 0.25em 0.5em; - - &:last-child { - border-left: 0.15em solid #CCC; - min-width: 40em; - } - } - - td:last-child { - font-family: monospace; - word-break: break-word; - background-color: #FFF; - font-size: 0.75em; - } + width: 100%; + max-width: 100%; + border: 0.15em solid #CCC; + background-color: #EEE; + font-size: 1.25em; + margin-bottom: 2em; + + th { + background-color: #CCC; + } + + td, th { + padding: 0.25em 0.5em; + + &:last-child { + border-left: 0.15em solid #CCC; + min-width: 40em; + } + } + + td:last-child { + font-family: monospace; + word-break: break-word; + background-color: #FFF; + font-size: 0.75em; + } } code { - color: #C33; - font-size: 0.9em; + color: #C33; + font-size: 0.9em; } pre { - font-size: 1.5em; - padding: 1em; - background-color: #333; - color: antiquewhite; - word-break: break-word; + font-size: 1.5em; + padding: 1em; + background-color: #333; + color: antiquewhite; + word-break: break-word; } .diff, .ecxdiff { - margin: 1em 0 5em 1em; - overflow: auto; - - ul { - list-style: none; - padding: 0; - margin: 0; - position: relative; - } - - li { - width: 40%; - display: inline-block; - padding: 0.5em; - margin: 0; - border-bottom: 1px solid #DDD; - //white-space: nowrap; - - &:nth-child(odd) { - margin-right: -3px; - float: left; - clear: left; - } - - ins { - color: #080;//lighten($colour-3, 33%); - } - - del { - color: #800; - } - } + margin: 1em 0 5em 1em; + overflow: auto; + + ul { + list-style: none; + padding: 0; + margin: 0; + position: relative; + } + + li { + width: 40%; + display: inline-block; + padding: 0.5em; + margin: 0; + border-bottom: 1px solid #DDD; + //white-space: nowrap; + + &:nth-child(odd) { + margin-right: -3px; + float: left; + clear: left; + } + + ins { + color: #080;//lighten($colour-3, 33%); + } + + del { + color: #800; + } + } } // Buttons h3 { - b { - padding: 10px 20px; - line-height: 50px; - - a, a:visited { - color: #FFF !important; - background-color: $colour-5; - text-decoration: none !important; - border-radius: 4px; - padding: 10px 15px; - margin-left: 20px; - border-bottom: 3px solid darken($colour-5, 10%); - -webkit-box-shadow: 0 0.5em 1.5em -0.75em #000; - box-shadow: 0 0.5em 1.5em -0.75em #000; - cursor: pointer !important; - } - - a:hover { - background-color: darken($colour-5, 10%); - } - } + b { + padding: 10px 20px; + line-height: 50px; + + a, a:visited { + color: #FFF !important; + background-color: $colour-5; + text-decoration: none !important; + border-radius: 4px; + padding: 10px 15px; + margin-left: 20px; + border-bottom: 3px solid darken($colour-5, 10%); + -webkit-box-shadow: 0 0.5em 1.5em -0.75em #000; + box-shadow: 0 0.5em 1.5em -0.75em #000; + cursor: pointer !important; + } + + a:hover { + background-color: darken($colour-5, 10%); + } + } } @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { - a[href^="tel"], a[href^="sms"] { - text-decoration: none; - color: $colour-1; - pointer-events: none; - cursor: default; - - .mobile_link & { - text-decoration: default; - color: $colour-1 !important; - pointer-events: auto; - cursor: default; - } - } + a[href^="tel"], a[href^="sms"] { + text-decoration: none; + color: $colour-1; + pointer-events: none; + cursor: default; + + .mobile_link & { + text-decoration: default; + color: $colour-1 !important; + pointer-events: auto; + cursor: default; + } + } } diff --git a/app/controllers/admin_controller.rb b/app/controllers/administration_controller.rb similarity index 94% rename from app/controllers/admin_controller.rb rename to app/controllers/administration_controller.rb index 1c03f0d..4c5d980 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/administration_controller.rb @@ -1,51 +1,51 @@ -require 'geocoder/calculations' - -class AdminController < ApplicationController - def new - return do_404 unless logged_in? && current_user.administrator? - @this_conference = Conference.new - @main_title = @page_title = 'articles.conferences.headings.new' - end - - def edit - return do_404 unless logged_in? && current_user.administrator? - @this_conference = Conference.find_by!(slug: params[:slug]) - @page_title = 'articles.conferences.headings.edit' - @main_title_vars = { vars: { title: @this_conference.title } } - render 'new' - end - - def save - conference = params[:id].present? ? Conference.find_by!(id: params[:id]) : Conference.new - - if params[:button] == 'save' - city = City.search(params[:city]) - conference.city_id = city.id - conference.conferencetype = params[:type] - conference.year = params[:year].to_i - conference.is_public = params[:is_public].present? - conference.is_featured = params[:is_featured].present? - conference.make_slug(true) - conference.save! - elsif params[:button] == 'delete' - conference.destroy - return redirect_to conferences_url - end - - redirect_to conference_url(conference.slug) - end - - rescue_from ActiveRecord::PremissionDenied do |exception| - if logged_in? - redirect_to :register - else - @register_template = :confirm_email - @page_title = "articles.conference_registration.headings.#{@this_conference.registration_status == :open ? '': 'Pre_'}Registration_Details" - render :register - end - end - - rescue_from ActiveRecord::RecordNotFound do |exception| - do_404 - end -end +require 'geocoder/calculations' + +class AdministrationController < ApplicationController + def new + return do_404 unless logged_in? && current_user.administrator? + @this_conference = Conference.new + @main_title = @page_title = 'articles.conferences.headings.new' + end + + def edit + return do_404 unless logged_in? && current_user.administrator? + @this_conference = Conference.find_by!(slug: params[:slug]) + @page_title = 'articles.conferences.headings.edit' + @main_title_vars = { vars: { title: @this_conference.title } } + render 'new' + end + + def save + conference = params[:id].present? ? Conference.find_by!(id: params[:id]) : Conference.new + + if params[:button] == 'save' + city = City.search(params[:city]) + conference.city_id = city.id + conference.conferencetype = params[:type] + conference.year = params[:year].to_i + conference.is_public = params[:is_public].present? + conference.is_featured = params[:is_featured].present? + conference.make_slug(true) + conference.save! + elsif params[:button] == 'delete' + conference.destroy + return redirect_to conferences_url + end + + redirect_to conference_url(conference.slug) + end + + rescue_from ActiveRecord::PremissionDenied do |exception| + if logged_in? + redirect_to :register + else + @register_template = :confirm_email + @page_title = "articles.conference_registration.headings.#{@this_conference.registration_status == :open ? '': 'Pre_'}Registration_Details" + render :register + end + end + + rescue_from ActiveRecord::RecordNotFound do |exception| + do_404 + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 131f5da..8dc06bd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,21 +1,19 @@ -module ActiveRecord - class PremissionDenied < RuntimeError - end -end - -class ApplicationController < LinguaFrancaApplicationController - # Prevent CSRF attacks by raising an exception. - # For APIs, you may want to use :null_session instead. +class ApplicationController < BaseController protect_from_forgery with: :exception, :except => [:do_confirm, :js_error, :admin_update] before_filter :capture_page_info helper_method :protect - @@test_host - @@test_location + # @@test_host + # @@test_location + + def default_url_options + { host: "#{request.protocol}#{request.host_with_port}", trailing_slash: true } + end def capture_page_info + # capture request info in case an error occurs if request.method == "GET" && (params[:controller] != 'application' || params[:action] != 'contact') session[:last_request] request_info = { @@ -27,14 +25,11 @@ class ApplicationController < LinguaFrancaApplicationController 'env' => Hash.new } } - request.env.each do | key, value | + request.env.each do |key, value| request_info['request']['env'][key.to_s] = value.to_s end session['request_info'] = request_info end - # set the translator to the current user if we're logged in - I18n.config.translator = current_user - I18n.config.callback = self # get the current conferences and set them globally status_hierarchy = { @@ -50,18 +45,16 @@ class ApplicationController < LinguaFrancaApplicationController @conference = @conferences.first # add some style sheets - @stylesheets ||= Array.new + @stylesheets ||= Set.new # add the translations stylesheet if translating @stylesheets << params[:controller] if params[:controller] == 'translations' - @_inline_scripts ||= [] + @_inline_scripts ||= Set.new @_inline_scripts << Rails.application.assets.find_asset('main.js').to_s - ActionMailer::Base.default_url_options = {:host => "#{request.protocol}#{request.host_with_port}"} - - if request.post? && params[:action] == 'do_confirm' - halt_redirection! - end + ActionMailer::Base.default_url_options = { + host: "#{request.protocol}#{request.host_with_port}" + } @alt_lang_urls = {} I18n.backend.enabled_locales.each do |locale| @@ -72,15 +65,10 @@ class ApplicationController < LinguaFrancaApplicationController # give each environment a different icon and theme colour so that we can easily see where we are. See https://css-tricks.com/give-development-domain-different-favicon-production @favicon = Rails.env.development? || Rails.env.preview? ? "favicon-#{Rails.env.to_s}.ico" : 'favicon.ico' @theme_colour = Rails.env.preview? ? '#EF57B4' : (Rails.env.development? ? '#D89E59' : '#00ADEF') - - # call the base method to detect the language - super end def home - @workshops = [] - - if @conference.present? + if @conference.present? && @conference.id.present? @workshops = Workshop.where(conference_id: @conference.id) if @conference.workshop_schedule_published @@ -94,54 +82,17 @@ class ApplicationController < LinguaFrancaApplicationController @is_policy_page = true end - def robots - render :text => File.read("config/robots-#{Rails.env.production? ? 'live' : 'dev'}.txt"), :content_type => 'text/plain' - end + # def self.set_host(host) + # @@test_host = host + # end - def humans - render :text => File.read("config/humans.txt"), :content_type => 'text/plain' - end + # def self.set_location(location) + # @@test_location = location + # end - def self.set_host(host) - @@test_host = host - end - - def self.set_location(location) - @@test_location = location - end - - def self.get_location() - @@test_location - end - - def do_404 - error_404(status: 404) - end - - def error_404(args = {}) - params[:_original_action] = params[:action] - params[:action] = 'error-404' - @page_title = 'page_titles.404.Page_Not_Found' - @main_title = 'error.404.title' - render 'application/404', args - end - - def do_403(template = nil) - @template = template - @page_title ||= 'page_titles.403.Access_Denied' - @main_title ||= @page_title - params[:_original_action] = params[:action] - params[:action] = 'error-403' - render 'application/permission_denied', status: 403 - end - - def error_500(exception = nil) - @page_title = 'page_titles.500.An_Error_Occurred' - @main_title = 'error.500.title' - params[:_original_action] = params[:action] - params[:action] = 'error-500' - render 'application/500', status: 500 - end + # def self.get_location() + # @@test_location + # end def js_error # send and email if this is production @@ -154,20 +105,30 @@ class ApplicationController < LinguaFrancaApplicationController begin # log the error - logger.info "Javascript exception: #{params[:message]}" - - UserMailer.send_mail(:error_report) do - [ - "A JavaScript error has occurred", - report, - params[:message], - nil, - request, - params, - current_user, - Time.now.strftime("%d/%m/%Y %H:%M") - ] - end# if Rails.env.preview? || Rails.env.production? + logger.info "A JavaScript error has occurred on #{params[:location]}:#{params[:lineNumber]}: #{params[:message]}" + + if Rails.env.preview? || Rails.env.production? + requestHash = { + 'remote_ip' => arg.remote_ip, + 'uuid' => arg.uuid, + 'original_url' => arg.original_url, + 'env' => Hash.new + } + request.env.each do | key, value | + requestHash['env'][key.to_s] = value.to_s + end + + send_mail(:error_report, + "A JavaScript error has occurred", + report, + params[:message], + nil, + requestHash, + params, + current_user, + Time.now.strftime("%d/%m/%Y %H:%M") + ) + end rescue Exception => exception2 logger.info exception2.to_s logger.info exception2.backtrace.join("\n") @@ -175,31 +136,27 @@ class ApplicationController < LinguaFrancaApplicationController render json: {} end - rescue_from ActiveRecord::RecordNotFound do |exception| - do_404 - end - - rescue_from ActiveRecord::PremissionDenied do |exception| - do_403 - end + def confirmation_sent(user) + template = 'login_confirmation_sent' + @page_title ||= 'page_titles.403.Please_Check_Email' - rescue_from AbstractController::ActionNotFound do |exception| - @banner_image = 'grafitti.jpg' - - if current_user - @page_title = nil#'page_titles.Please_Login' - do_403 'not_a_translator' - #return - else - @page_title = 'page_titles.403.Please_Login' - do_403 'translator_login' + if (request.present? && request.referrer.present? && conference = /^\/conferences\/(\w+)\/register\/?$/.match(request.referrer.gsub(/^https?:\/\/.*?\//, '/'))) + @this_conference = Conference.find_by!(slug: conference[1]) + @banner_image = @this_conference.cover_url + template = 'conferences/email_confirm' end + + do_403 template end def locale_not_enabled!(locale = nil) locale_not_available!(locale) end + def locale_not_available + locale_not_available!(params[:locale]) + end + def locale_not_available!(locale = nil) set_default_locale params[:_original_action] = params[:action] @@ -210,11 +167,13 @@ class ApplicationController < LinguaFrancaApplicationController render 'application/locale_not_available', status: 404 end - rescue_from StandardError do |exception| - handle_exception exception + unless Rails.env.test? + rescue_from StandardError do |exception| + handle_exception exception - # show the error page - error_500 exception + # show the error page + error_500 exception + end end def handle_exception(exception) @@ -223,19 +182,28 @@ class ApplicationController < LinguaFrancaApplicationController logger.info exception.backtrace.join("\n") # send and email if this is production - suppress(Exception) do - UserMailer.send_mail(:error_report) do - [ - "An error has occurred in #{Rails.env}", - nil, - exception.to_s, - exception.backtrace.join("\n"), - request, - params, - current_user, - Time.now.strftime("%d/%m/%Y %H:%M") - ] - end if Rails.env.preview? || Rails.env.production? + if Rails.env.preview? || Rails.env.production? + suppress(Exception) do + requestHash = { + 'remote_ip' => arg.remote_ip, + 'uuid' => arg.uuid, + 'original_url' => arg.original_url, + 'env' => Hash.new + } + request.env.each do | key, value | + requestHash['env'][key.to_s] = value.to_s + end + send_mail(:error_report, + "An error has occurred in #{Rails.env}", + nil, + exception.to_s, + exception.backtrace.join("\n"), + requestHash, + params, + current_user, + Time.now.strftime("%d/%m/%Y %H:%M") + ) + end end # raise the error if we are in development so that we can debug it @@ -250,37 +218,6 @@ class ApplicationController < LinguaFrancaApplicationController end end - def generate_confirmation(user, url, expiry = nil) - if user.is_a? String - user = User.find_user(user) - - # if the user doesn't exist, just show them a 403 - do_403 unless user.present? - end - expiry ||= (Time.now + 12.hours) - session[:confirm_uid] = user.id - - unless user.locale.present? - user.locale = I18n.locale - user.save - end - - # send the confirmation email and make sure it get sent as quickly as possible - UserMailer.send_mail :email_confirmation do - EmailConfirmation.create(user_id: user.id, expiry: expiry, url: url) - end - end - - def user_settings - @conferences = Array.new - if logged_in? - Conference.all.each do | conference | - @conferences << conference if conference.host? current_user - end - end - @main_title = @page_title = 'page_titles.user_settings.Your_Account' - end - def contact @main_title = @page_title = 'page_titles.contact.Contact_Us' end @@ -290,32 +227,28 @@ class ApplicationController < LinguaFrancaApplicationController if params[:reason] == 'conference' - @conference.organizations.each do | org | - org.users.each do | user | - email_list << user.named_email + @conference.organizations.each do |org| + org.users.each do |user| + # email_list << user.named_email end end end - UserMailer.send_mail(:contact) do - [ + send_mail(:contact, current_user || params[:email], params[:subject], params[:message], email_list - ] - end + ) request_info = session['request_info'] || { 'request' => request, 'params' => params } - UserMailer.send_mail(:contact_details) do - [ + send_mail(:contact_details, current_user || params[:email], params[:subject], params[:message], request_info['request'], request_info['params'] - ] - end + ) redirect_to contact_sent_path end @@ -326,31 +259,8 @@ class ApplicationController < LinguaFrancaApplicationController render 'contact' end - def update_user_settings - return do_403 unless logged_in? - current_user.firstname = params[:name] - current_user.lastname = nil - current_user.languages = (params[:languages] || { I18n.locale.to_s => true }).keys - current_user.is_subscribed = params[:email_subscribe].present? - current_user.save - redirect_to settings_path - end - - def do_confirm(settings = nil) - settings ||= {:template => 'login_confirmation_sent'} + def confirm_user if params[:email] - # see if we've already sent the confirmation email and are just confirming - # the email address - if params[:token] - user = User.find_user(params[:email]) - confirm(user) - return - end - user = User.get(params[:email]) - - # generate the confirmation, send the email and show the 403 - referrer = params[:dest] || (request.present? && request.referer.present? ? request.referer.gsub(/^.*?\/\/.*?\//, '/') : settings_path) - generate_confirmation(params[:email], referrer) template = 'login_confirmation_sent' @page_title ||= 'page_titles.403.Please_Check_Email' @@ -365,75 +275,44 @@ class ApplicationController < LinguaFrancaApplicationController @banner_image ||= 'grafitti.jpg' @page_title ||= 'page_titles.403.Please_Login' - do_403 (template || 'translator_login') + do_403 template else do_404 end end - def confirm(uid = nil) - @confirmation = EmailConfirmation.find_by_token(params[:token]) - - unless @confirmation.present? - @token_not_found = true - return do_404 - end - - confirm_user = nil - if uid.is_a?(User) - confirm_user = uid - uid = confirm_user.id - end - # check to see if we were given a user id to confirm against - # if we were, make sure it was the same one - if (uid ||= (params[:uid] || session[:confirm_uid])) - if uid == @confirmation.user_id - session[:uid] = nil - confirm_user ||= User.find uid - auto_login(confirm_user) - else - @confirmation.delete - end - - redirect_to (@confirmation.url || '/') - return - end - - @banner_image = 'grafitti.jpg' - @page_title = 'page_titles.403.Please_Confirm_Email' - do_403 'login_confirm' + def error_404(args = {}) + params[:_original_action] = params[:action] + params[:action] = 'error-404' + @page_title = 'page_titles.404.Page_Not_Found' + @main_title = 'error.404.title' + super(args) end - def translator_request + def do_403(template = nil) @banner_image = 'grafitti.jpg' - @page_title = 'page_titles.403.Translator_Request_Sent' - do_403 'translator_request_sent' - end - - def user_logout - logout() - redirect_to (params[:url] || '/') - end + + unless current_user + @page_title = 'page_titles.403.Please_Login' + end - def find_user - user = User.find_user(params[:e]) + @template = template + @page_title ||= 'page_titles.403.Access_Denied' + @main_title ||= @page_title + params[:_original_action] = params[:action] + params[:action] = 'error-403' - if user.present? - return render json: { - name: user.name, - email: user.email, - exists: true - } - end - render json: { - name: I18n.t('user.not_found'), - email: nil, - exists: false - } + super(template) end - def login_user(u) - auto_login(u) + def error_500(exception = nil) + @page_title = 'page_titles.500.An_Error_Occurred' + @main_title = 'error.500.title' + params[:_original_action] = params[:action] + params[:action] = 'error-500' + @exception = exception + + super(exception) end def on_translation_change(object, data, locale, translator_id) @@ -443,8 +322,8 @@ class ApplicationController < LinguaFrancaApplicationController if object.respond_to?(:get_translators) object.get_translators(data, locale).each do |id, user| if user.id != current_user.id && user.id != translator_id - UserMailer.send_mail mailer, user.locale do - { :args => [object, data, locale, user, translator] } + LinguaFranca.with_locale user.locale do + send_mail(:send, mailer, object.id, data, locale, user.id, translator.id) end end end @@ -457,8 +336,8 @@ class ApplicationController < LinguaFrancaApplicationController if object.respond_to?(:get_translators) object.get_translators(data).each do |id, user| if user.id != current_user.id - UserMailer.send_mail mailer, user.locale do - { :args => [object, data, user, current_user] } + LinguaFranca.with_locale user.locale do + send_mail(:send, mailer, object.id, data, user.id, current_user.id) end end end @@ -469,23 +348,32 @@ class ApplicationController < LinguaFrancaApplicationController # log it logger.info "Missing translation found for: #{key}" - # send and email if this is production - begin - UserMailer.send_mail(:error_report) do - [ - "A missing translation found in #{Rails.env}", - "

A translation for #{key} in #{locale.to_s} was found. The text that was rendered to the user was:

#{str || 'nil'}
", - exception.to_s, - nil, - request, - params, - current_user, - Time.now.strftime("%d/%m/%Y %H:%M") - ] - end if Rails.env.preview? || Rails.env.production? - rescue Exception => exception2 - logger.info exception2.to_s - logger.info exception2.backtrace.join("\n") + # send an email if this is production + if Rails.env.preview? || Rails.env.production? + begin + requestHash = { + 'remote_ip' => arg.remote_ip, + 'uuid' => arg.uuid, + 'original_url' => arg.original_url, + 'env' => Hash.new + } + request.env.each do | key, value | + requestHash['env'][key.to_s] = value.to_s + end + send_mail(:error_report, + "A missing translation found in #{Rails.env}", + "

A translation for #{key} in #{locale.to_s} was found. The text that was rendered to the user was:

#{str || 'nil'}
", + exception.to_s, + nil, + requestHash, + params, + current_user.id, + Time.now.strftime("%d/%m/%Y %H:%M") + ) + rescue Exception => exception2 + logger.info exception2.to_s + logger.info exception2.backtrace.join("\n") + end end end @@ -545,8 +433,8 @@ class ApplicationController < LinguaFrancaApplicationController @schedule = {} day_1 = conference.start_date.wday - @workshop_blocks.each_with_index do | info, block | - info['days'].each do | block_day | + @workshop_blocks.each_with_index do |info, block| + info['days'].each do |block_day| day_diff = block_day.to_i - day_1 day_diff += 7 if day_diff < 0 day = (conference.start_date + day_diff.days).to_date @@ -559,9 +447,10 @@ class ApplicationController < LinguaFrancaApplicationController end end - @workshops.each do | workshop | + @workshops.each do |workshop| if workshop.block.present? block = @workshop_blocks[workshop.block['block'].to_i] + day_diff = workshop.block['day'].to_i - day_1 day_diff += 7 if day_diff < 0 day = (conference.start_date + day_diff.days).to_date @@ -573,7 +462,7 @@ class ApplicationController < LinguaFrancaApplicationController end end - @meals.each do | time, meal | + @meals.each do |time, meal| day = meal['day'].to_date time = meal['time'].to_f @schedule[day] ||= {} @@ -584,7 +473,7 @@ class ApplicationController < LinguaFrancaApplicationController @schedule[day][:times][time][:item] = meal end - @events.each do | event | + @events.each do |event| if event.present? && event.start_time.present? && event.end_time.present? day = event.start_time.midnight.to_date time = event.start_time.hour.to_f + (event.start_time.min / 60.0) @@ -598,13 +487,13 @@ class ApplicationController < LinguaFrancaApplicationController end @schedule = @schedule.sort.to_h - @schedule.each do | day, data | + @schedule.each do |day, data| @schedule[day][:times] = data[:times].sort.to_h end - @schedule.each do | day, data | + @schedule.each do |day, data| last_event = nil - data[:times].each do | time, time_data | + data[:times].each do |time, time_data| if last_event.present? @schedule[day][:times][last_event][:next_event] = time end @@ -613,8 +502,8 @@ class ApplicationController < LinguaFrancaApplicationController @schedule[day][:num_locations] = (data[:locations] || []).size end - @schedule.deep_dup.each do | day, data | - data[:times].each do | time, time_data | + @schedule.deep_dup.each do |day, data| + data[:times].each do |time, time_data| if time_data[:next_event].present? || time_data[:length] > 0.5 span = 0.5 length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length] @@ -631,7 +520,7 @@ class ApplicationController < LinguaFrancaApplicationController @schedule = @schedule.sort.to_h - @schedule.each do | day, data | + @schedule.each do |day, data| @schedule[day][:times] = data[:times].sort.to_h @schedule[day][:locations] ||= {} @@ -639,19 +528,19 @@ class ApplicationController < LinguaFrancaApplicationController @schedule[day][:locations][0] = :add if do_analyze || @schedule[day][:locations].empty? if do_analyze - data[:times].each do | time, time_data | + data[:times].each do |time, time_data| if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present? ids = time_data[:item][:workshops].keys - (0..ids.length).each do | i | + (0..ids.length).each do |i| if time_data[:item][:workshops][ids[i]].present? workshop_i = time_data[:item][:workshops][ids[i]][:workshop] conflicts = {} - (i+1..ids.length).each do | j | + (i+1..ids.length).each do |j| workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil if workshop_i.present? && workshop_j.present? - workshop_i.active_facilitators.each do | facilitator_i | - workshop_j.active_facilitators.each do | facilitator_j | + workshop_i.active_facilitators.each do |facilitator_i| + workshop_j.active_facilitators.each do |facilitator_j| if facilitator_i.id == facilitator_j.id @schedule[day][:times][time][:status] ||= {} @schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << { @@ -673,7 +562,7 @@ class ApplicationController < LinguaFrancaApplicationController needs = JSON.parse(workshop_i.needs || '[]').map &:to_sym amenities = JSON.parse(location.amenities || '[]').map &:to_sym - needs.each do | need | + needs.each do |need| @schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << { name: :need_not_available, need: need, @@ -689,7 +578,7 @@ class ApplicationController < LinguaFrancaApplicationController # collect common interested users interests = [] - (0..ids.length).each do | j | + (0..ids.length).each do |j| workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil if workshop_i.present? && workshop_j.present? && workshop_i.id != workshop_j.id interests = interests | workshop_j.interested.map { | u | u.user_id } @@ -744,4 +633,17 @@ class ApplicationController < LinguaFrancaApplicationController def html_value(value) return value.present? && ActionView::Base.full_sanitizer.sanitize(value).strip.present? ? value : nil end + + # send the confirmation email and make sure it get sent as quickly as possible + def send_confirmation(confirmation) + send_mail(:email_confirmation, confirmation.id) + end + + def send_mail(*args) + if Rails.env.preview? || Rails.env.production? + UserMailer.delay(queue: Rails.env.to_s).send(*args) + else + UserMailer.send(*args).deliver_now + end + end end diff --git a/app/controllers/conference_administration_controller.rb b/app/controllers/conference_administration_controller.rb index 733efd4..236c0c8 100644 --- a/app/controllers/conference_administration_controller.rb +++ b/app/controllers/conference_administration_controller.rb @@ -151,7 +151,7 @@ class ConferenceAdministrationController < ApplicationController }, data: [], } - @organizations.each do | org | + @organizations.each do |org| if org.present? address = org.locations.first @excel_data[:data] << { @@ -167,7 +167,7 @@ class ConferenceAdministrationController < ApplicationController } end end - return respond_to do | format | + return respond_to do |format| format.xlsx { render xlsx: :stats, filename: "organizations" } end end @@ -183,7 +183,7 @@ class ConferenceAdministrationController < ApplicationController if request.format.xlsx? logger.info "Generating stats.xls" - return respond_to do | format | + return respond_to do |format| format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } end end @@ -194,7 +194,7 @@ class ConferenceAdministrationController < ApplicationController @donation_count = 0 @donations = 0 @food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 } - @registrations.each do | r | + @registrations.each do |r| if view_context.registration_status(r) == :registered @completed_registrations += 1 @@ -223,7 +223,7 @@ class ConferenceAdministrationController < ApplicationController if request.format.xlsx? logger.info "Generating stats.xls" - return respond_to do | format | + return respond_to do |format| format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } end else @@ -233,7 +233,7 @@ class ConferenceAdministrationController < ApplicationController @donation_count = 0 @donations = 0 @food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 } - @registrations.each do | r | + @registrations.each do |r| if view_context.registration_status(r) == :registered @completed_registrations += 1 @@ -275,7 +275,7 @@ class ConferenceAdministrationController < ApplicationController }, data: [], } - @hosts.each do | id, host | + @hosts.each do |id, host| data = (host.housing_data || {}) host_data = { name: host.user.name, @@ -283,7 +283,7 @@ class ConferenceAdministrationController < ApplicationController email: host.user.email, phone: data['phone'], availability: data['availability'].present? && data['availability'][1].present? ? view_context.date_span(data['availability'][0].to_date, data['availability'][1].to_date) : '', - considerations: ((data['considerations'] || []).map { | consideration | view_context._"articles.conference_registration.host.considerations.#{consideration}" }).join(', '), + considerations: ((data['considerations'] || []).map { |consideration| view_context._"articles.conference_registration.host.considerations.#{consideration}" }).join(', '), empty: '', guests: { columns: [:name, :area, :email, :arrival_departure, :allergies, :food, :companion, :city], @@ -304,8 +304,8 @@ class ConferenceAdministrationController < ApplicationController } } - @housing_data[id][:guests].each do | space, space_data | - space_data.each do | guest_id, guest_data | + @housing_data[id][:guests].each do |space, space_data| + space_data.each do |guest_id, guest_data| guest = guest_data[:guest] if guest.present? companion = view_context.companion(guest) @@ -326,7 +326,7 @@ class ConferenceAdministrationController < ApplicationController @excel_data[:data] << host_data end - return respond_to do | format | + return respond_to do |format| format.xlsx { render xlsx: :stats, filename: "housing" } end end @@ -458,7 +458,7 @@ class ConferenceAdministrationController < ApplicationController }, data: [] } - User.AVAILABLE_LANGUAGES.each do | l | + User.AVAILABLE_LANGUAGES.each do |l| @excel_data[:keys]["language_#{l}".to_sym] = "languages.#{l.to_s}" end ConferenceRegistration.all_spaces.each do |s| @@ -468,7 +468,7 @@ class ConferenceAdministrationController < ApplicationController ConferenceRegistration.all_considerations.each do |c| @excel_data[:keys][c] = "articles.conference_registration.host.considerations.#{c.to_s}" end - @registrations.each do | r | + @registrations.each do |r| user = r.user_id ? User.where(id: r.user_id).first : nil if user.present? companion = view_context.companion(r) @@ -528,7 +528,7 @@ class ConferenceAdministrationController < ApplicationController last_day: availability[1].present? ? view_context.date(availability[1].to_date, :span_same_year_date_1) : '' } } - User.AVAILABLE_LANGUAGES.each do | l | + User.AVAILABLE_LANGUAGES.each do |l| can_speak = ((user.languages || []).include? l.to_s) data["language_#{l}".to_sym] = (can_speak ? (view_context._'articles.conference_registration.questions.bike.yes') : '') data[:raw_values]["language_#{l}".to_sym] = can_speak @@ -573,12 +573,12 @@ class ConferenceAdministrationController < ApplicationController first_day: view_context.conference_days_options_list(:before), last_day: view_context.conference_days_options_list(:after) } - User.AVAILABLE_LANGUAGES.each do | l | + User.AVAILABLE_LANGUAGES.each do |l| @column_options["language_#{l}".to_sym] = [ [(view_context._"articles.conference_registration.questions.bike.yes"), true] ] end - ConferenceRegistration.all_considerations.each do | c | + ConferenceRegistration.all_considerations.each do |c| @column_options[c.to_sym] = [ [(view_context._"articles.conference_registration.questions.bike.yes"), true] ] @@ -589,7 +589,7 @@ class ConferenceAdministrationController < ApplicationController def get_housing_data @hosts = {} @guests = {} - ConferenceRegistration.where(:conference_id => @this_conference.id).each do | registration | + ConferenceRegistration.where(:conference_id => @this_conference.id).each do |registration| if registration.can_provide_housing @hosts[registration.id] = registration elsif registration.housing.present? && registration.housing != 'none' @@ -603,11 +603,11 @@ class ConferenceAdministrationController < ApplicationController @housing_data = {} @hosts_affected_by_guests = {} - @hosts.each do | id, host | + @hosts.each do |id, host| @hosts[id].housing_data ||= {} @housing_data[id] = { guests: {}, space: {} } @hosts[id].housing_data['space'] ||= {} - @hosts[id].housing_data['space'].each do | s, size | + @hosts[id].housing_data['space'].each do |s, size| size = (size || 0).to_i @housing_data[id][:guests][s.to_sym] = {} @housing_data[id][:space][s.to_sym] = size @@ -616,7 +616,7 @@ class ConferenceAdministrationController < ApplicationController @guests_housed = 0 - @guests.each do | guest_id, guest | + @guests.each do |guest_id, guest| data = guest.housing_data || {} @hosts_affected_by_guests[guest_id] ||= [] @@ -651,7 +651,7 @@ class ConferenceAdministrationController < ApplicationController end companions = data['companions'] || [] - companions.each do | companion | + companions.each do |companion| user = User.find_user(companion) if user.present? reg = ConferenceRegistration.find_by( @@ -678,10 +678,10 @@ class ConferenceAdministrationController < ApplicationController end end - @hosts.each do | id, host | + @hosts.each do |id, host| host_data = host.housing_data - @hosts[id].housing_data['space'].each do | space, size | + @hosts[id].housing_data['space'].each do |space, size| # make sure the host isn't overbooked space = space.to_sym space_available = (size || 0).to_i @@ -755,7 +755,7 @@ class ConferenceAdministrationController < ApplicationController end else do_404 - return nil + return true end return false @@ -790,7 +790,7 @@ class ConferenceAdministrationController < ApplicationController end def admin_update_description - params[:info].each do | locale, value | + params[:info].each do |locale, value| @this_conference.set_column_for_locale(:info, locale, html_value(value)) end @this_conference.save @@ -811,7 +811,7 @@ class ConferenceAdministrationController < ApplicationController def admin_update_payment_message begin - params[:payment_message].each do | locale, value | + params[:payment_message].each do |locale, value| @this_conference.set_column_for_locale(:payment_message, locale, html_value(value)) end @this_conference.save @@ -883,7 +883,7 @@ class ConferenceAdministrationController < ApplicationController end user_changed = false - params.each do | key, value | + params.each do |key, value| case key.to_sym when :city if value.present? @@ -964,7 +964,7 @@ class ConferenceAdministrationController < ApplicationController do_404 end - return nil + return true end def admin_update_housing @@ -1004,7 +1004,7 @@ class ConferenceAdministrationController < ApplicationController do_404 end - return nil + return true end def admin_update_broadcast @@ -1014,36 +1014,32 @@ class ConferenceAdministrationController < ApplicationController @send_to = params[:send_to] @register_template = :administration if params[:button] == 'send' - view_context.broadcast_to(@send_to).each do | user | - UserMailer.send_mail :broadcast do - [ + view_context.broadcast_to(@send_to).each do |user| + send_mail(:broadcast, "#{request.protocol}#{request.host_with_port}", @subject, @body, - user, - @this_conference - ] - end + user.id, + @this_conference.id + ) end redirect_to administration_step_path(@this_conference.slug, :broadcast_sent) - return nil + return true elsif params[:button] == 'preview' @send_to_count = view_context.broadcast_to(@send_to).size @broadcast_step = :preview elsif params[:button] == 'test' @broadcast_step = :test - UserMailer.send_mail :broadcast do - [ + send_mail(:broadcast, "#{request.protocol}#{request.host_with_port}", @subject, @body, - current_user, - @this_conference - ] - end + current_user.id, + @this_conference.id + ) @send_to_count = view_context.broadcast_to(@send_to).size end - return true + return false end def admin_update_locations @@ -1106,14 +1102,14 @@ class ConferenceAdministrationController < ApplicationController end do_404 - return nil + return true end def admin_update_events case params[:button] when 'edit' redirect_to edit_event_path(@this_conference.slug, params[:id]) - return nil + return true when 'save' if params[:id].present? event = Event.find_by!(conference_id: @this_conference.id, id: params[:id]) @@ -1127,11 +1123,11 @@ class ConferenceAdministrationController < ApplicationController event.end_time = event.start_time + params[:time_span].to_f.hours # save translations - (params[:info] || {}).each do | locale, value | + (params[:info] || {}).each do |locale, value| event.set_column_for_locale(:title, locale, html_value(value), current_user.id) unless value = event._title(locale) end - (params[:title] || {}).each do | locale, value | + (params[:title] || {}).each do |locale, value| event.set_column_for_locale(:info, locale, value, current_user.id) unless value = event._info(locale) end @@ -1143,9 +1139,9 @@ class ConferenceAdministrationController < ApplicationController end do_404 - return nil + return true end - + def admin_update_workshop_times case params[:button] when 'save_block' @@ -1209,7 +1205,7 @@ class ConferenceAdministrationController < ApplicationController @location = params[:location] @event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil - @workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do | workshop | + @workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do |workshop| @ordered_workshops[workshop.id] = workshop end @@ -1251,7 +1247,7 @@ class ConferenceAdministrationController < ApplicationController def get_empty(hash, keys) keys = [keys] unless keys.is_a?(Array) - keys.each do | key | + keys.each do |key| return key unless hash[key].present? end return nil diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 803c77e..1a23fe1 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -2,6 +2,7 @@ require 'geocoder/calculations' require 'rest_client' class ConferencesController < ApplicationController + def list @page_title = 'articles.conferences.headings.Conference_List' @conference_list = { future: [], passed: [] } @@ -17,7 +18,7 @@ class ConferencesController < ApplicationController set_conference do_403 unless @this_conference.is_public || @this_conference.host?(current_user) - @workshops = Workshop.where(:conference_id => @conference.id) + @workshops = Workshop.where(:conference_id => @this_conference.id) if @this_conference.workshop_schedule_published @event_dlg = true @@ -59,7 +60,7 @@ class ConferencesController < ApplicationController steps = nil return do_404 unless registration_steps.present? - @register_template = :administration if params[:admin_step].present? + # @register_template = :administration if params[:admin_step].present? @errors = {} @warnings = [] @@ -72,8 +73,19 @@ class ConferencesController < ApplicationController @register_template = steps[steps.find_index($1.to_sym) - 1] elsif form_step == :paypal_confirm if @registration.present? && @registration.payment_confirmation_token == params[:confirmation_token] - @amount = PayPal!.details(params[:token]).amount.total - @registration.payment_info = {:payer_id => params[:PayerID], :token => params[:token], :amount => @amount}.to_yaml + if Rails.env.test? + @amount = params[:amount].to_f + info = YAML.load(@registration.payment_info) + info[:amount] = @amount + @registration.payment_info = info.to_yaml + else + @amount = PayPal!.details(params[:token]).amount.total + @registration.payment_info = { + payer_id: params[:PayerID], + token: params[:token], + amount: @amount + }.to_yaml + end @amount = (@amount * 100).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2') @@ -86,7 +98,7 @@ class ConferencesController < ApplicationController info = YAML.load(@registration.payment_info) @amount = nil status = nil - if ENV['RAILS_ENV'] == 'test' + if Rails.env.test? status = info[:status] @amount = info[:amount] else @@ -114,7 +126,7 @@ class ConferencesController < ApplicationController case form_step when :confirm_email - return do_confirm + return confirm_email(params[:email], params[:token], register_path(@this_conference.slug)) when :contact_info if params[:name].present? && params[:name].gsub(/[\s\W]/, '').present? current_user.firstname = params[:name].squish @@ -188,18 +200,23 @@ class ConferencesController < ApplicationController amount = params[:amount].to_f if amount > 0 - @registration.payment_confirmation_token = ENV['RAILS_ENV'] == 'test' ? 'token' : Digest::SHA256.hexdigest(rand(Time.now.to_f * 1000000).to_i.to_s) - @registration.save - - host = "#{request.protocol}#{request.host_with_port}" - response = PayPal!.setup( - PayPalRequest(amount), - register_paypal_confirm_url(@this_conference.slug, :paypal_confirm, @registration.payment_confirmation_token), - register_paypal_confirm_url(@this_conference.slug, :paypal_cancel, @registration.payment_confirmation_token), - noshipping: true, - version: 204 - ) - if ENV['RAILS_ENV'] != 'test' + # we can't really test paypal integration in our tests, so we'll fake it instead + if Rails.env.test? + @registration.payment_confirmation_token = 'token' + @registration.payment_info = {amount: amount}.to_yaml + @registration.save! + redirect_to 'https://www.paypal.com' + else + @registration.payment_confirmation_token = Digest::SHA256.hexdigest(rand(Time.now.to_f * 1000000).to_i.to_s) + @registration.save! + pp = PayPal! + response = pp.setup( + PayPalRequest(amount), + register_paypal_confirm_url(@this_conference.slug, :paypal_confirm, @registration.payment_confirmation_token), + register_paypal_confirm_url(@this_conference.slug, :paypal_cancel, @registration.payment_confirmation_token), + noshipping: true, + version: 204 + ) redirect_to response.redirect_uri end return @@ -219,7 +236,7 @@ class ConferencesController < ApplicationController # this step is only completed if a payment has been made if form_step != :payment || (@registration.registration_fees_paid || 0) > 0 @registration.steps_completed ||= [] - @registration.steps_completed << form_step + @registration.steps_completed << form_step.to_s @registration.steps_completed.uniq! end end @@ -334,9 +351,7 @@ class ConferencesController < ApplicationController steps -= [:questions] # if this is a housing provider that is not attending the conference, remove these steps - if @registration.is_attending == 'n' - steps -= [:payment, :workshops] - end + steps -= [:payment, :workshops] if @registration.is_attending == 'n' else steps -= [:hosting] end @@ -344,8 +359,6 @@ class ConferencesController < ApplicationController steps -= [:hosting, :questions] end - steps += [:administration] if conference.host?(current_user) - return steps end @@ -394,11 +407,11 @@ class ConferencesController < ApplicationController def PayPalRequest(amount) Paypal::Payment::Request.new( - :currency_code => 'USD', # if nil, PayPal use USD as default - :description => 'Conference Registration', # item description - :quantity => 1, # item quantity - :amount => amount.to_f, # item value - :custom_fields => { + currency_code: 'USD', # if nil, PayPal use USD as default + description: 'Conference Registration', # item description + quantity: 1, # item quantity + amount: amount.to_f, # item value + custom_fields: { CARTBORDERCOLOR: "00ADEF", LOGOIMG: "https://en.bikebike.org/assets/bblogo-paypal.png" } diff --git a/app/controllers/oauths_controller.rb b/app/controllers/oauths_controller.rb deleted file mode 100644 index decccbb..0000000 --- a/app/controllers/oauths_controller.rb +++ /dev/null @@ -1,101 +0,0 @@ -class OauthsController < ApplicationController - skip_before_filter :require_login - - # sends the user on a trip to the provider, - # and after authorizing there back to the callback url. - def oauth - set_callback - session[:oauth_last_url] = params[:dest] || request.referer - login_at(auth_params[:provider]) - end - - def callback - set_callback - - user_info = (sorcery_fetch_user_hash auth_params[:provider] || {})[:user_info] - - email = user_info['email'] - fb_id = user_info['id'] - - # try to find the user by facebook id - user = User.find_by_fb_id(fb_id) - - # otherwise find the user by email - unless user.present? - # only look if the email address is present - user = User.find_user(email) if email.present? - end - - # create the user if the email is not recognized - if user.nil? - if email.present? - user = User.create(email: email, firstname: user_info['name'], fb_id: fb_id, locale: I18n.locale) - else - session[:oauth_update_user_info] = user_info - return redirect_to oauth_update_path - end - elsif user.fb_id.blank? || user.email.blank? - user.email = email - user.fb_id = fb_id - user.save! - end - - if user.present? && user.email.present? - # log in the user - auto_login(user) - end - - oauth_last_url = (session[:oauth_last_url] || home_path) - session.delete(:oauth_last_url) - redirect_to oauth_last_url - end - - def update - @main_title = @page_title = 'articles.conference_registration.headings.email_confirm' - @errors = { email: flash[:error] } if flash[:error].present? - render 'application/update_user' - end - - def save - unless params[:email].present? - return redirect_to oauth_update_path - end - - user = User.find_user(params[:email]) - - if user.present? - flash[:error] = :exists - return redirect_to oauth_update_path - end - - # create the user - user = User.new(email: params[:email], firstname: session[:oauth_update_user_info]['name'], fb_id: session[:oauth_update_user_info]['id']) - user.save! - - # log in - auto_login(user) - - # clear out the session - oauth_last_url = (session[:oauth_last_url] || home_path) - session.delete(:oauth_last_url) - session.delete(:oauth_update_user_info) - - # go to our final destination - redirect_to oauth_last_url - end - - private - def auth_params - params.permit(:code, :provider) - end - - def set_callback - # force https for prod - protocol = Rails.env.preview? || Rails.env.production? ? 'https://' : request.protocol - - # build the callback url - Sorcery::Controller::Config.send(params[:provider]).callback_url = - "#{protocol}#{request.env['HTTP_HOST']}/oauth/callback?provider=facebook" - end - -end \ No newline at end of file diff --git a/app/controllers/workshops_controller.rb b/app/controllers/workshops_controller.rb index 04b0409..ea7a64b 100644 --- a/app/controllers/workshops_controller.rb +++ b/app/controllers/workshops_controller.rb @@ -1,10 +1,10 @@ - class WorkshopsController < ApplicationController + def workshops set_conference set_conference_registration! - @workshops = Workshop.where(:conference_id => @this_conference.id) - @my_workshops = Workshop.joins(:workshop_facilitators).where(:workshop_facilitators => {:user_id => current_user.id}, :conference_id => @this_conference.id) + @workshops = Workshop.where(conference_id: @this_conference.id) + @my_workshops = @workshops.select { |w| w.active_facilitator?(current_user) } render 'workshops/index' end @@ -58,7 +58,7 @@ class WorkshopsController < ApplicationController @is_translating ||= false if @is_translating - return do_404 if @translation.to_s == @workshop.locale.to_s || !I18n.backend.enabled_locales.include?(@translation.to_s) + return do_404 unless @translation.to_s != @workshop.locale.to_s && LinguaFranca.locale_enabled?(@translation.to_sym) return do_403 unless @workshop.can_translate?(current_user, @translation) @title = @workshop._title(@translation) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb new file mode 100644 index 0000000..a9b1979 --- /dev/null +++ b/app/helpers/admin_helper.rb @@ -0,0 +1,163 @@ +module AdminHelper + + def administration_steps + { + info: [:administrators, :dates, :description, :poster], + payment: [:payment_message, :suggested_amounts, :paypal], + registration: [:registration_status, :stats, :registrations, :broadcast], + housing: [:providers, :housing], + events: [:locations, :meals, :events], + schedule: [:workshop_times, :schedule, :publish_schedule] + } + end + + def administration_sub_steps + { + location_edit: :locations, + event_edit: :events + } + end + + def get_administration_group(administration_step) + admin_step = administration_step.to_sym + admin_step = administration_sub_steps[admin_step] if administration_sub_steps[admin_step].present? + administration_steps.each do | group, steps | + steps.each do | step | + return group if step == admin_step + end + end + + return nil + end + + def broadcast_to(to, conference = nil) + conference ||= @this_conference || @conference + + users = [] + + case to.to_sym + when :registered + ConferenceRegistration.where(conference_id: conference.id).each do | r | + users << r.user if ((r.steps_completed || []).include? 'questions') && r.user.present? && r.is_attending != 'n' + end + when :pre_registered + ConferenceRegistration.where(conference_id: conference.id).each do | r | + users << r.user if registration_status(r) == :preregistered && r.is_attending != 'n' + end + when :workshop_facilitators + user_hash = {} + Workshop.where(conference_id: conference.id).each do | w | + w.active_facilitators.each do | u | + user_hash[u.id] ||= u if u.present? + end + end + users = user_hash.values + when :unregistered + ConferenceRegistration.where(conference_id: conference.id).each do | r | + users << r.user if registration_status(r) == :unregistered && r.is_attending != 'n' + end + when :housing_providers + ConferenceRegistration.where(conference_id: conference.id, can_provide_housing: true).each do | r | + users << r.user if r.user.present? + end + when :guests + ConferenceRegistration.where(conference_id: conference.id, housing: 'house').each do | r | + users << r.user if r.user.present? && r.is_attending != 'n' + end + when :all + User.all.each do | u | + users << u if u.present? && (u.is_subscribed.nil? || u.is_subscribed) + end + end + + return users + end + + def get_housing_match(host, guest, space) + housing_data = guest.housing_data || [] + + if housing_data['host'].present? + if housing_data['host'] == host.id + return space == housing_data['space'] ? :selected_space : :other_space + end + + return :other_host + end + + if space_matches?(space, guest.housing) && available_dates_match?(host, guest) + return :good_match + end + + return :bad_match + end + + def get_workshop_match(workshop, day, block, location) + if workshop.event_location_id.present? && workshop.present? + if (Date.parse params[:day]).wday == workshop.block['day'] && block == workshop.block['block'].to_i + return :selected_space + end + + if location.present? && location.id == workshop.event_location_id + return :other_space + end + + return :other_host + end + + if location.present? + needs = JSON.parse(workshop.needs || '[]').map &:to_sym + amenities = JSON.parse(location.amenities || '[]').map &:to_sym + + if (needs & amenities).length < needs.length + return :bad_match + end + end + + (((((@schedule[@day] || {})[:times] || {})[@time] || {})[:item] || {})[:workshops] || {}).each do | l, w | + if w[:workshop].id != workshop.id + f_a = w[:workshop].active_facilitators.map { | f | f.id } + f_b = workshop.active_facilitators.map { | f | f.id } + if (f_a & f_b).present? + return :bad_match + end + end + end + + # housing_data = guest.housing_data || [] + + # if housing_data['host'].present? + # if housing_data['host'] == host.id + # return space == housing_data['space'] ? :selected_space : :other_space + # end + + # return :other_host + # end + + # if space_matches?(space, guest.housing) && available_dates_match?(host, guest) + # return :good_match + # end + + # return :bad_match + return :good_match + end + + def space_matches?(host_space, guest_space) + return false unless host_space.present? && guest_space.present? + + if host_space.to_s == 'bed_space' || host_space.to_s == 'floor_space' + return guest_space.to_s == 'house' + end + + return host_space.to_s == 'tent_space' && guest_space.to_s == 'tent' + end + + def available_dates_match?(host, guest) + return false unless host.housing_data['availability'].present? && host.housing_data['availability'][1].present? + if host.housing_data['availability'][0] <= guest.arrival && + host.housing_data['availability'][1] >= guest.departure + return true + end + + return false + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 56ca8a7..563131d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,521 +1,14 @@ -require 'redcarpet' +require 'lingua_franca/form_helper' module ApplicationHelper + include PageHelper include RegistrationHelper - - @@keyQueue = nil - @@translationsOnThisPage = nil - @@lastTranslation = nil - @@allTranslations = nil - @@no_banner = true - @@banner_attribution_details = nil - @@banner_image = nil - @@has_content = true - @@front_page = false - @@body_class = nil - @@test_location = nil - - def init_vars - @@keyQueue = nil - @@no_banner = true - @@banner_attribution_details = nil - @@banner_image = nil - @@has_content = true - @@front_page = false - @@body_class = nil - end - - def this_is_the_front_page - @@front_page = true - end - - def header_is_fixed - @fixed_header = true - end - - def is_header_fixed? - @fixed_header ||= false - end - - def is_this_the_front_page? - return @@front_page - end - - def header_classes - classes = Array.new - classes << 'fixed' if is_header_fixed? - return classes - end - - def ThereAreTranslationsOnThisPage? - @@translationsOnThisPage - end - - def get_all_translations - @@allTranslations - end - - def title(page_title) - content_for(:title) { page_title.to_s } - end - - def description(page_description) - content_for(:description) { page_description.to_s } - end - - def banner_image(banner_image, name: nil, id: nil, user_id: nil, src: nil) - @@no_banner = false - @@banner_image = banner_image - if (name || id || user_id || src) - @@banner_attribution_details = {:name => name, :id => id, :user_id => user_id, :src => src} - end - content_for(:banner_image) { banner_image.to_s } - end - - def banner_attrs(banner_image) - @@no_banner = false - if banner_image.length > 0 - @@banner_image = banner_image - return {style: 'background-image: url(' + banner_image + ');', class: 'has-image' } - end - {class: 'no-image'} - end - - def has_banner? - !@@no_banner - end - - def has_content? - @@has_content - end - - def has_no_content - @@has_content = false - end - - def banner_title(banner_title) - @@no_banner = false - content_for(:banner) { ('

' + banner_title.to_s + '

').html_safe } - end - - def add_stylesheet(sheet) - @stylesheets ||= [] - @stylesheets << sheet unless @stylesheets.include?(sheet) - end - - def stylesheets - html = '' - Rack::MiniProfiler.step('inject_css') do - html += inject_css! - end - (@stylesheets || []).each do |css| - Rack::MiniProfiler.step("inject_css #{css}") do - html += inject_css! css.to_s - end - end - html += stylesheet_link_tag 'i18n-debug' if request.params['i18nDebug'] - return html.html_safe - end - - def add_inline_script(script) - @_inline_scripts ||= [] - script = Rails.application.assets.find_asset("#{script.to_s}.js").to_s - @_inline_scripts << script unless @_inline_scripts.include?(script) - end - - def inline_scripts - return '' unless @_inline_scripts.present? - "".html_safe - end - - def banner_attribution - if @@banner_image && @@banner_attribution_details - src = @@banner_attribution_details[:src] - attribution = '
' - if src == 'panoramio' - attribution += '© ' + - _('Banner_image_provided_by_panoramio_user') + - ' ' + @@banner_attribution_details[:name] + '' + - '' + _('Photos_provided_by_Panoramio_are_under_the_copyright_of_their_owners') + '' - end - attribution += '
' - attribution.html_safe - end - end - - def dom_ready(&block) - content_for(:dom_ready, &block) - end - - def body_class(c) - @@body_class ||= Array.new - @@body_class << (c.is_a?(Array) ? c.join(' ') : c) - end - - def page_style - classes = Array.new - - classes << 'has-translations' if ThereAreTranslationsOnThisPage? - classes << 'no-content' unless @@has_content - classes << 'has-banner-image' if @@banner_image - classes << @@body_class.join(' ') if @@body_class - classes << 'fixed-banner' if is_header_fixed? - - if params[:controller] - classes << params[:action] - unless params[:controller] == 'application' - classes << params[:controller] - - if params[:action] - classes << "#{params[:controller]}-#{params[:action]}" - end - end - end - return classes - end - - def yield_or_default(section, default = '') - content_for?(section) ? content_for(section) : default - end - - def _translate_me(translation) - @@translationsOnThisPage = true - datakeys = '' - translation['vars'].each { |key, value| datakeys += ' data-var-' + key.to_s + '="' + value.to_s.gsub('"', '"') + '"' } - ('' + (translation['html'] || translation['untranslated']) + '').to_s.html_safe - end - - def _do_translate(key, vars, behavior, behavior_size, locale) - translation = {'key' => key, 'lang' => '0', 'vars' => vars} - v = vars.dup - begin - v[:raise] = true - options = {:raise => true} - if locale - options[:locale] = locale.to_sym - end - translation['untranslated'] = I18n.translate(key, v, options) - translation['lang'] = locale.to_s - translation['is_translated'] = true - - hash = Hash.new - translations = Translation.where(["locale = ? AND key LIKE ?", locale.to_s, key + '%']).take(6).each { |o| hash[o.key] = o.value } - translation['translated'] = hash.to_json.gsub('"', '"') - rescue I18n::MissingTranslationData - default_translation = I18n::MissingTranslationExceptionHandler.note(key, behavior, behavior_size) - translation['untranslated'] = default_translation - end - return translation - end - - def _can_translate?() - false - end - - def off_screen(text, id = nil) - content_tag(:span, text.html_safe, id: id, class: 'screen-reader-text') - end - - def url_for_locale(locale, url = nil) - return url unless locale.present? - - unless url.present? - new_params = params.merge({action: (params[:_original_action] || params[:action])}) - new_params.delete(:_original_action) - - if Rails.env.development? || Rails.env.test? - return url_for(new_params.merge({lang: locale.to_s})) - end - - subdomain = Rails.env.preview? ? "preview-#{locale.to_s}" : locale.to_s - return url_for(new_params.merge(host: "#{subdomain}.bikebike.org")) - end - - return url if Rails.env.development? || Rails.env.test? - return "https://preview-#{locale.to_s}.bikebike.org#{url}" if Rails.env.preview? - "https://#{locale.to_s}.bikebike.org#{url}" - end - - def registration_steps(conference = @conference) - { - pre: [:policy, :contact_info, :workshops], - open: [:policy, :contact_info, :questions, :hosting, :payment, :workshops] - }[@this_conference.registration_status] - end - - def registration_status(registration) - return :unregistered if registration.nil? - return registration.status - end - - def sortable(objects, id = 'id', url: nil, &block) - result = '