From 830ebd2a54b2e7c9ae08811315c862e01ec937ec Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 1 Aug 2013 12:26:01 -0600 Subject: [PATCH] completely update --- .gitignore | 18 + Gemfile | 60 +++ Gemfile.lock | 267 +++++++++++ Procfile | 2 + Rakefile | 7 + Readme.md | 47 ++ app/assets/.DS_Store | Bin 0 -> 6148 bytes app/assets/images/.DS_Store | Bin 0 -> 6148 bytes app/assets/images/debut_dark.png | Bin 0 -> 19901 bytes app/assets/javascripts/application.js | 16 + app/assets/stylesheets/ads.css.scss | 7 + app/assets/stylesheets/application.css | 13 + app/assets/stylesheets/global.css.scss.erb | 88 ++++ app/controllers/admin_controller.rb | 12 + app/controllers/ads_controller.rb | 78 ++++ app/controllers/application_controller.rb | 3 + app/controllers/cats_controller.rb | 38 ++ app/controllers/sessions_controller.rb | 18 + app/controllers/sub_cats_controller.rb | 40 ++ app/controllers/users_controller.rb | 41 ++ app/helpers/application_helper.rb | 2 + app/mailers/.gitkeep | 0 app/mailers/user_mailer.rb | 3 + app/models/.gitkeep | 0 app/models/ad.rb | 19 + app/models/asset.rb | 5 + app/models/cat.rb | 5 + app/models/sub_cat.rb | 3 + app/models/user.rb | 14 + app/views/ads/_ad_summary.slim | 7 + app/views/ads/_form.slim | 14 + app/views/ads/index.slim | 2 + app/views/ads/new.slim | 1 + app/views/ads/show.slim | 0 app/views/layouts/application.slim | 38 ++ app/views/sessions/new.slim | 11 + app/views/shared/_error_block.html.erb | 7 + app/views/users/_form.slim | 19 + app/views/users/edit.slim | 0 app/views/users/new.slim | 1 + app/views/users/show.slim | 9 + config.ru | 4 + config/application.rb | 68 +++ config/boot.rb | 6 + config/database.yml | 7 + config/environment.rb | 5 + config/environments/development.rb | 43 ++ config/environments/production.rb | 73 +++ config/environments/test.rb | 37 ++ config/initializers/backtrace_silencers.rb | 7 + config/initializers/inflections.rb | 15 + config/initializers/mime_types.rb | 5 + config/initializers/secret_token.rb | 7 + config/initializers/session_store.rb | 8 + config/initializers/simple_form.rb | 142 ++++++ config/initializers/simple_form_bootstrap.rb | 45 ++ config/initializers/sorcery.rb | 437 ++++++++++++++++++ config/initializers/wrap_parameters.rb | 14 + config/locales/en.yml | 5 + config/locales/simple_form.en.yml | 26 ++ config/routes.rb | 15 + config/unicorn.rb | 24 + db/migrate/20130711205743_sorcery_core.rb | 14 + .../20130711205744_sorcery_reset_password.rb | 17 + .../20130711205745_sorcery_remember_me.rb | 15 + ...20130711205746_sorcery_activity_logging.rb | 19 + .../20130711205852_create_delayed_jobs.rb | 22 + db/migrate/20130712230139_create_ads.rb | 16 + ...0712230451_add_name_and_address_to_user.rb | 10 + db/migrate/20130715154627_create_cats.rb | 11 + db/schema.rb | 80 ++++ db/seeds.rb | 7 + doc/README_FOR_APP | 2 + lib/assets/.gitkeep | 0 lib/generators/print/USAGE | 9 + lib/generators/print/print_generator.rb | 24 + lib/tasks/.gitkeep | 0 lib/templates/erb/scaffold/_form.html.erb | 13 + log/.gitkeep | 0 public/404.html | 26 ++ public/422.html | 26 ++ public/500.html | 25 + public/favicon.ico | 0 public/robots.txt | 5 + script/delayed_job | 5 + script/rails | 6 + test/fixtures/ads.yml | 22 + test/fixtures/cats.yml | 12 + test/fixtures/users.yml | 12 + test/mailers/user_mailer_test.rb | 7 + test/models/ad_test.rb | 7 + test/models/cat_test.rb | 7 + test/models/user_test.rb | 7 + vendor/assets/javascripts/.gitkeep | 0 vendor/assets/stylesheets/.gitkeep | 0 vendor/plugins/.gitkeep | 0 96 files changed, 2334 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Procfile create mode 100644 Rakefile create mode 100644 Readme.md create mode 100644 app/assets/.DS_Store create mode 100644 app/assets/images/.DS_Store create mode 100644 app/assets/images/debut_dark.png create mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/stylesheets/ads.css.scss create mode 100644 app/assets/stylesheets/application.css create mode 100644 app/assets/stylesheets/global.css.scss.erb create mode 100644 app/controllers/admin_controller.rb create mode 100644 app/controllers/ads_controller.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/cats_controller.rb create mode 100644 app/controllers/sessions_controller.rb create mode 100644 app/controllers/sub_cats_controller.rb create mode 100644 app/controllers/users_controller.rb create mode 100644 app/helpers/application_helper.rb create mode 100644 app/mailers/.gitkeep create mode 100644 app/mailers/user_mailer.rb create mode 100644 app/models/.gitkeep create mode 100644 app/models/ad.rb create mode 100644 app/models/asset.rb create mode 100644 app/models/cat.rb create mode 100644 app/models/sub_cat.rb create mode 100644 app/models/user.rb create mode 100644 app/views/ads/_ad_summary.slim create mode 100644 app/views/ads/_form.slim create mode 100644 app/views/ads/index.slim create mode 100644 app/views/ads/new.slim create mode 100644 app/views/ads/show.slim create mode 100644 app/views/layouts/application.slim create mode 100644 app/views/sessions/new.slim create mode 100644 app/views/shared/_error_block.html.erb create mode 100644 app/views/users/_form.slim create mode 100644 app/views/users/edit.slim create mode 100644 app/views/users/new.slim create mode 100644 app/views/users/show.slim create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/secret_token.rb create mode 100644 config/initializers/session_store.rb create mode 100644 config/initializers/simple_form.rb create mode 100644 config/initializers/simple_form_bootstrap.rb create mode 100644 config/initializers/sorcery.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/locales/simple_form.en.yml create mode 100644 config/routes.rb create mode 100644 config/unicorn.rb create mode 100644 db/migrate/20130711205743_sorcery_core.rb create mode 100644 db/migrate/20130711205744_sorcery_reset_password.rb create mode 100644 db/migrate/20130711205745_sorcery_remember_me.rb create mode 100644 db/migrate/20130711205746_sorcery_activity_logging.rb create mode 100644 db/migrate/20130711205852_create_delayed_jobs.rb create mode 100644 db/migrate/20130712230139_create_ads.rb create mode 100644 db/migrate/20130712230451_add_name_and_address_to_user.rb create mode 100644 db/migrate/20130715154627_create_cats.rb create mode 100644 db/schema.rb create mode 100644 db/seeds.rb create mode 100644 doc/README_FOR_APP create mode 100644 lib/assets/.gitkeep create mode 100644 lib/generators/print/USAGE create mode 100644 lib/generators/print/print_generator.rb create mode 100644 lib/tasks/.gitkeep create mode 100644 lib/templates/erb/scaffold/_form.html.erb create mode 100644 log/.gitkeep create mode 100644 public/404.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/favicon.ico create mode 100644 public/robots.txt create mode 100755 script/delayed_job create mode 100755 script/rails create mode 100644 test/fixtures/ads.yml create mode 100644 test/fixtures/cats.yml create mode 100644 test/fixtures/users.yml create mode 100644 test/mailers/user_mailer_test.rb create mode 100644 test/models/ad_test.rb create mode 100644 test/models/cat_test.rb create mode 100644 test/models/user_test.rb create mode 100644 vendor/assets/javascripts/.gitkeep create mode 100644 vendor/assets/stylesheets/.gitkeep create mode 100644 vendor/plugins/.gitkeep diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dbaa2ff --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +# Ignore bundler config +/.bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 + +# Ignore all logfiles and tempfiles. +/log/*.log +/tmp + +# Ignore application configuration +/config/application.yml diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..acc28e6 --- /dev/null +++ b/Gemfile @@ -0,0 +1,60 @@ +source 'https://rubygems.org' + +gem 'rails', '3.2.11' + +gem 'pg' + +# front-end +gem 'jquery-rails' +gem 'anjlab-bootstrap-rails', :require => 'bootstrap-rails', :github => 'anjlab/bootstrap-rails', :branch => '3.0.0' + +# authentication +gem 'sorcery' + +# templates +gem 'slim' + +# server +gem 'unicorn' +gem 'foreman' + +# background +gem 'delayed_job_active_record' + +# searching +gem 'ransack' + +# pagination +gem 'kaminari' + +# forms +gem 'simple_form' + +# file uploading +gem 'paperclip' + +# environment variables +gem 'figaro' + +group :assets do + gem 'sass-rails', '~> 3.2.3' + gem 'coffee-rails', '~> 3.2.1' + gem 'therubyracer', :platforms => :ruby + gem 'uglifier', '>= 1.0.3' + gem 'bootstrap-sass' +end + +group :development, :test, :staging do + gem 'minitest-rails' +end + +group :test do + gem 'minitest-rails-capybara' + gem 'factory_girl_rails' + gem 'mocha', :require => false + gem 'simplecov', :require => false + gem 'faker' + gem 'launchy' + gem 'webmock' + gem 'turn' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..71b05a1 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,267 @@ +GIT + remote: git://github.com/anjlab/bootstrap-rails.git + revision: 4ec1018b3dd8078f3489bc53f2ac92782b6442f2 + branch: 3.0.0 + specs: + anjlab-bootstrap-rails (3.0.0.rc1) + railties (>= 3.0) + sass (>= 3.2) + +GEM + remote: https://rubygems.org/ + specs: + actionmailer (3.2.11) + actionpack (= 3.2.11) + mail (~> 2.4.4) + actionpack (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.4) + rack (~> 1.4.0) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.2.1) + activemodel (3.2.11) + activesupport (= 3.2.11) + builder (~> 3.0.0) + activerecord (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activeresource (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) + activesupport (3.2.11) + i18n (~> 0.6) + multi_json (~> 1.0) + addressable (2.3.5) + ansi (1.4.3) + arel (3.0.2) + bcrypt-ruby (3.0.1) + bootstrap-sass (2.3.2.0) + sass (~> 3.2) + builder (3.0.4) + capybara (2.1.0) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + climate_control (0.0.3) + activesupport (>= 3.0) + cocaine (0.5.1) + climate_control (>= 0.0.3, < 1.0) + coffee-rails (3.2.2) + coffee-script (>= 2.2.0) + railties (~> 3.2.0) + coffee-script (2.2.0) + coffee-script-source + execjs + coffee-script-source (1.6.3) + crack (0.4.0) + safe_yaml (~> 0.9.0) + delayed_job (3.0.5) + activesupport (~> 3.0) + delayed_job_active_record (0.4.4) + activerecord (>= 2.1.0, < 4) + delayed_job (~> 3.0) + dotenv (0.8.0) + erubis (2.7.0) + execjs (1.4.0) + multi_json (~> 1.0) + factory_girl (4.2.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.2.1) + factory_girl (~> 4.2.0) + railties (>= 3.0.0) + faker (1.1.2) + i18n (~> 0.5) + faraday (0.8.7) + multipart-post (~> 1.1) + figaro (0.7.0) + bundler (~> 1.0) + rails (>= 3, < 5) + foreman (0.63.0) + dotenv (>= 0.7) + thor (>= 0.13.6) + hike (1.2.3) + httpauth (0.2.0) + i18n (0.6.4) + journey (1.0.4) + jquery-rails (3.0.4) + railties (>= 3.0, < 5.0) + thor (>= 0.14, < 2.0) + json (1.8.0) + jwt (0.1.8) + multi_json (>= 1.5) + kaminari (0.14.1) + actionpack (>= 3.0.0) + activesupport (>= 3.0.0) + kgio (2.8.0) + launchy (2.3.0) + addressable (~> 2.3) + libv8 (3.11.8.17) + mail (2.4.4) + i18n (>= 0.4.0) + mime-types (~> 1.16) + treetop (~> 1.4.8) + metaclass (0.0.1) + mime-types (1.23) + mini_portile (0.5.1) + minitest (4.7.5) + minitest-capybara (0.3.0) + capybara (~> 2.0) + minitest (~> 4.0) + rake + minitest-matchers (1.3.0) + minitest (~> 4.7) + minitest-metadata (0.4.0) + minitest (~> 4.7) + minitest-rails (0.9.2) + minitest (~> 4.7) + rails (>= 3.0) + minitest-rails-capybara (0.9.0) + capybara (~> 2.0) + minitest-capybara (~> 0.1) + minitest-matchers (~> 1.2) + minitest-metadata (~> 0.3) + minitest-rails (~> 0.9.1) + mocha (0.14.0) + metaclass (~> 0.0.1) + multi_json (1.7.7) + multipart-post (1.2.0) + nokogiri (1.6.0) + mini_portile (~> 0.5.0) + oauth (0.4.7) + oauth2 (0.8.1) + faraday (~> 0.8) + httpauth (~> 0.1) + jwt (~> 0.1.4) + multi_json (~> 1.0) + rack (~> 1.2) + paperclip (3.4.2) + activemodel (>= 3.0.0) + activerecord (>= 3.0.0) + activesupport (>= 3.0.0) + cocaine (~> 0.5.0) + mime-types + pg (0.15.1) + polyamorous (0.5.0) + activerecord (~> 3.0) + polyglot (0.3.3) + rack (1.4.5) + rack-cache (1.2) + rack (>= 0.4) + rack-ssl (1.3.3) + rack + rack-test (0.6.2) + rack (>= 1.0) + rails (3.2.11) + actionmailer (= 3.2.11) + actionpack (= 3.2.11) + activerecord (= 3.2.11) + activeresource (= 3.2.11) + activesupport (= 3.2.11) + bundler (~> 1.0) + railties (= 3.2.11) + railties (3.2.11) + actionpack (= 3.2.11) + activesupport (= 3.2.11) + rack-ssl (~> 1.3.2) + rake (>= 0.8.7) + rdoc (~> 3.4) + thor (>= 0.14.6, < 2.0) + raindrops (0.11.0) + rake (10.1.0) + ransack (0.7.2) + actionpack (~> 3.0) + activerecord (~> 3.0) + polyamorous (~> 0.5.0) + rdoc (3.12.2) + json (~> 1.4) + ref (1.0.5) + safe_yaml (0.9.4) + sass (3.2.9) + sass-rails (3.2.6) + railties (~> 3.2.0) + sass (>= 3.1.10) + tilt (~> 1.3) + simple_form (2.1.0) + actionpack (~> 3.0) + activemodel (~> 3.0) + simplecov (0.7.1) + multi_json (~> 1.0) + simplecov-html (~> 0.7.1) + simplecov-html (0.7.1) + slim (2.0.0) + temple (~> 0.6.5) + tilt (~> 1.3, >= 1.3.3) + sorcery (0.8.2) + bcrypt-ruby (~> 3.0.0) + oauth (~> 0.4.4) + oauth2 (~> 0.8.0) + sprockets (2.2.2) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + temple (0.6.5) + therubyracer (0.11.4) + libv8 (~> 3.11.8.12) + ref + thor (0.18.1) + tilt (1.4.1) + treetop (1.4.14) + polyglot + polyglot (>= 0.3.1) + turn (0.9.6) + ansi + tzinfo (0.3.37) + uglifier (2.1.1) + execjs (>= 0.3.0) + multi_json (~> 1.0, >= 1.0.2) + unicorn (4.6.3) + kgio (~> 2.6) + rack + raindrops (~> 0.7) + webmock (1.13.0) + addressable (>= 2.2.7) + crack (>= 0.3.2) + xpath (2.0.0) + nokogiri (~> 1.3) + +PLATFORMS + ruby + +DEPENDENCIES + anjlab-bootstrap-rails! + bootstrap-sass + coffee-rails (~> 3.2.1) + delayed_job_active_record + factory_girl_rails + faker + figaro + foreman + jquery-rails + kaminari + launchy + minitest-rails + minitest-rails-capybara + mocha + paperclip + pg + rails (= 3.2.11) + ransack + sass-rails (~> 3.2.3) + simple_form + simplecov + slim + sorcery + therubyracer + turn + uglifier (>= 1.0.3) + unicorn + webmock diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..7934897 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb +worker: bundle exec rake jobs:work diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..7689a3e --- /dev/null +++ b/Rakefile @@ -0,0 +1,7 @@ +#!/usr/bin/env rake +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Classie::Application.load_tasks diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..e2245e5 --- /dev/null +++ b/Readme.md @@ -0,0 +1,47 @@ +Classie +========= + +Uses +---- + +* Postgresql +* JQuery +* SCSS +* Slim +* Bootstrap +* Minitest +* Factory Girl +* Unicorn +* Figaro for environment variables + +Any of these can be changed pretty easily. + +Usage +----- + +Clone to folder with name you choose for project +``` +git clone git@github.com:nwalkingshaw/blueprint.git [FOLDER_NAME] +``` + +Change config/database.yml file +``` +rake db:create:all +``` + +Generate file for figaro +``` +rails g figaro:install +``` + +Rename app using the included generator +``` +rails g print new_app_name +``` + +Add to config/application.rb if deploying to Heroku +``` +config.assets.initialize_on_precompile = false +``` + +### Customize!! diff --git a/app/assets/.DS_Store b/app/assets/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9d2ad6c35400164b8b02bde44e9fb419a06eb7f6 GIT binary patch literal 6148 zcmeHKOH0E*5Z-NTO;8~hp~uB@kv@ca@DM@;k3tGPSkZ)(HV~82r1nsw!JEIvf8+0Q zW_NQ4<}6}oVD_7x$8Pq6?1M4JolVeZ%wmigpokoe8bNn$sG*Y)xg2B8Qh%GS{3!8j z2KtLG{Ps2r*%R~Ff>po&(_ckln)P~LywPkOv=0r_G>&J}Fbpkz)(wNX z@2&5poq5?Nb-cBV+zsLh;9eYAGigOLzyPvXp0c9Y;yL0DoCi<`NPE!~iis4D2xj z`cN>A_Lu`&Ix#>D)H8tlg8)UeH5Llx)&UJ(pE2G-L;)M$5{N>ht+7xD5fH9Q0aYp2 zPYkZg!7p^4t+7z3${Ck4!#H~8^6|pu?BEwNopDyPE(St~#vK~XTTKm!Eq$|V3gxQ}#XP{jq>kY{Tw6yhl8 Rm*s$T5s-vXLk#=^1K)q!Nl5?z literal 0 HcmV?d00001 diff --git a/app/assets/images/.DS_Store b/app/assets/images/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..30fc14640ce16ea9622f15ae042b466e38f288e3 GIT binary patch literal 6148 zcmeH~F;Bxl427SeLnS2Ck?}?*B>usvYLS@v0YE5XplT7Kd$#`U@@yZ7C@`=vpl8W` zImga5-w^iz*nGFT1ZDuHbXV*>jLq-6kL;*rj7sM--f)W*?(vG}QT6u;?>%MDBRcE` z{TFz_22a=P?L)WTcC7Osc||{`+u^_{69Ewr0TB=Z5%?_upS`r{Nvfgo`kLizleHX`jjr&9ar6t=5hhmhH@!R#%($so4&To%x)$ zv$Ye7#qP|PD2LTlMG+8zA%Wvu&V2qa=|7zRhfP|EfC&660ybIPEarTrHd{w8=d-rZ t@8}=K+9+p;QA~|d%!QBQvoCeUuX(>V?Ng(j`Dmx=kAQQLiNIeFcn5Tf7<~W$ literal 0 HcmV?d00001 diff --git a/app/assets/images/debut_dark.png b/app/assets/images/debut_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..17a4d6b42defcc8ebbad993bc91a2030f6c690ed GIT binary patch literal 19901 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 AbN~PV literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 0000000..5733810 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,16 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// the compiled file. +// +// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD +// GO AFTER THE REQUIRES BELOW. +// +//= require jquery +//= require jquery_ujs +//= require twitter/bootstrap +//= require_tree . diff --git a/app/assets/stylesheets/ads.css.scss b/app/assets/stylesheets/ads.css.scss new file mode 100644 index 0000000..9bae46c --- /dev/null +++ b/app/assets/stylesheets/ads.css.scss @@ -0,0 +1,7 @@ +.ad-summary { + margin-bottom: 15px; + padding-bottom: 10px; + border-bottom: 2px solid #CCCCCC; + .title {} + .description {} +} diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css new file mode 100644 index 0000000..3192ec8 --- /dev/null +++ b/app/assets/stylesheets/application.css @@ -0,0 +1,13 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the top of the + * compiled file, but it's generally better to create a new file per style scope. + * + *= require_self + *= require_tree . + */ diff --git a/app/assets/stylesheets/global.css.scss.erb b/app/assets/stylesheets/global.css.scss.erb new file mode 100644 index 0000000..bff5990 --- /dev/null +++ b/app/assets/stylesheets/global.css.scss.erb @@ -0,0 +1,88 @@ +// variables have to be set before importing bootstrap +// set variables here + +// set the correct sprite paths +$iconSpritePath: image-path('glyphicons-halflings.png'); +$iconWhiteSpritePath: image-path('glyphicons-halflings-white.png'); + +$navbarBackground: #555; +$navbarBackgroundHighlight: #888; +$navbarText: #eee; +$navbarLinkColor: #eee; + + +// now import +@import 'twitter/bootstrap'; + +h1, h2, h3, h4, h5 { + font-family: 'Exo', sans-serif; + font-weight:400; +} +.navbar-inverse .navbar-inner { + padding-top: 0px; + background-image: url(<%= asset_path('debut_dark.png') %>); + background-repeat: repeat; + background-color:#333; +} +.navbar .brand { + font-family: 'Exo', sans-serif; + font-size:30px; + font-size: 28px; + font-weight: 400; + color: #eee; + text-shadow: 0 2px 0 #000; +} +.navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus { + color: #eee; + text-decoration: none; + background-color: #222; + margin-top:-10px; + padding-top:20px; + padding-bottom:18px; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} +.navbar .nav > li > a { + float: none; + font-size:16px; + padding: 10px 15px 10px; + color: #eee; + text-decoration: none; + text-shadow: 0 1px 0 #000; +} +.navbar .nav > li > a:hover { + color:#0088cc; +} +.navbar .nav a.btn { + padding: 4px 12px; + margin: 5px 8px; +} +.navbar .nav a.btn:hover { + color: #FFFFFF; + background-position: 0px; +} +.navbar .nav a.btn:active { + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); +} +.collapse { + background-color: transparent; +} +@media (max-width: 979px) { +.nav-collapse .nav > li > a:hover, .nav-collapse .nav > li > a:focus, .nav-collapse .dropdown-menu a:hover, .nav-collapse .dropdown-menu a:focus { + background-color: #000; + color:#fff; + } +} +.well { + background-color: #fff; + border: 1px solid #ddd; + background: -webkit-linear-gradient(top, #ffffff, #f9f9f9); + background: -moz-linear-gradient(top, #ffffff, #f9f9f9); + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb new file mode 100644 index 0000000..67d4fcd --- /dev/null +++ b/app/controllers/admin_controller.rb @@ -0,0 +1,12 @@ +class AdminController < ApplicationController + + def index + @ads = Ad.all + + # for categories + @cats = Cat.find(:all, :order => "position") + @cat = Cat.new + @sub_cat = SubCat.new + end + +end diff --git a/app/controllers/ads_controller.rb b/app/controllers/ads_controller.rb new file mode 100644 index 0000000..0ec036d --- /dev/null +++ b/app/controllers/ads_controller.rb @@ -0,0 +1,78 @@ +class AdsController < ApplicationController + + def index + @ads = Ad.search(params[:search]) + end + + def browse + @cats = Cat.find(:all, :order => "position") + end + + def search + @ads = Ad.search(params[:search]) + end + + def show + @ad = Ad.find(params[:id]) + @assets = @ad.assets + @user = User.find(params[:user_id]) + end + + def new + if logged_in? + @ad = Ad.new + @cats = Cat.find(:all, :conditions => ["admin is null OR admin = ?", false]) + else + redirect_to login_path, notice: "Sign in to create an ad. Don't have an account? Click Sign Up to create one." + end + end + + def change_sub_cats_select + @cat_val = params[:cat_val] + @cat = Cat.find(@cat_val) + @subcats = @cat.sub_cats.find(:all, :conditions => ["admin is null OR admin = ?", false]) + + respond_to do |wants| + wants.json { render :json => @subcats } + end + end + + def create + @ad = current_user.ads.build(params[:ad].merge(city: current_user.city, state: current_user.state, views: 0)) + if @ad.save + redirect_to user_path(current_user) + else + render :new + end + end + + def edit + @ad = Ad.find(params[:id]) + @cats = Cat.find(:all, :conditions => ["admin is null OR admin = ?", false]) + @assets = @ad.assets + @asset = Asset.new + end + + def update + @ad = Ad.find(params[:id]) + if @ad.update_attributes(params[:ad]) + flash[:notice] = "Successfully updated ad." + redirect_to(edit_user_ad_path(current_user, @ad)) + else + render :action => 'edit' + end + end + + def destroy + @ad = Ad.find(params[:id]) + @ad.destroy + flash[:notice] = "Successfully destroyed ad." + redirect_to(username_path(current_user)) + end + + def views + @ad = Ad.find(params[:id]) + @ad.increment!(:views) + end + +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..e8065d9 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,3 @@ +class ApplicationController < ActionController::Base + protect_from_forgery +end diff --git a/app/controllers/cats_controller.rb b/app/controllers/cats_controller.rb new file mode 100644 index 0000000..06b44bc --- /dev/null +++ b/app/controllers/cats_controller.rb @@ -0,0 +1,38 @@ +class CatsController < ApplicationController + + def index + @cats = Cat.all + end + + def show + @cat = Cat.find(params[:id]) + end + + def create + @cat = Cat.new(params[:cat]) + if @cat.save + flash[:notice] = "Successfully created cat." + redirect_to(admin_path) + else + render :action => 'new' + end + end + + def edit + @cat = Cat.find(params[:id]) + end + + def update + @cat = Cat.find(params[:id]) + @cat.update_attributes(params[:cat]) + flash.now[:notice] = "Successfully updated cat." + end + + def destroy + @cat = Cat.find(params[:id]) + @cat.destroy + flash[:notice] = "Successfully destroyed cat." + redirect_to(admin_path) + end + +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..8b350e5 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,18 @@ +class SessionsController < ApplicationController + + def create + @user = login(params[:email], params[:password]) + if @user + redirect_to user_path(@user), notice: 'Logged in. Atta kid!' + else + flash[:error] = 'The Email or Password you entered is incorrect' + redirect_to signin_path + end + end + + def destroy + logout + redirect_to root_path, notice: 'Logged Out' + end + +end diff --git a/app/controllers/sub_cats_controller.rb b/app/controllers/sub_cats_controller.rb new file mode 100644 index 0000000..3f407e2 --- /dev/null +++ b/app/controllers/sub_cats_controller.rb @@ -0,0 +1,40 @@ +class SubCatsController < ApplicationController + + def new + @sub_cat = SubCat.new + end + + def create + @cat = Cat.find(params[:cat_id]) + @sub_cat = @cat.sub_cats.build(params[:sub_cat]) + if @sub_cat.save + redirect_to(admin_path) + end + end + + def prioritize_sub_cats + cat = Cat.find(params[:cat_id]) + sub_cats = cat.sub_cats + sub_cats.each do |sub_cat| + sub_cat.position = params["sub_cat"].index(sub_cat.id.to_s) + sub_cat.save + end + render :nothing + end + + def update + @cat = Cat.find(params[:cat_id]) + @sub_cat = @cat.sub_cats.find(params[:id]) + @sub_cat.update_attributes(params[:sub_cat]) + end + + def destroy + @sub_cat = SubCat.find(params[:id]) + @sub_cat.destroy + redirect_to(admin_path) + end + + def edit + end + +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..fe62ec4 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,41 @@ +class UsersController < ApplicationController + + def new + @user = User.new + end + + def create + @user = User.new(params[:user]) + if @user.save + auto_login(@user) + redirect_to root_path, notice: "Thanks for signing up!" + else + render :new + end + end + + def update + if current_user.update_attributes(params[:user]) + current_user.ads.each do |ad| + ad.city = current_user.city + ad.state = current_user.state + ad.save + end + flash[:notice] = "Your account and your ads have been updated." + else + flash[:error] = "Something went wrong and your account was not updated. Please try again." + end + redirect_to(username_path(current_user)) + end + + def show + if logged_in? + @ads = current_user.ads + else + session[:return_to] = "my_ads" + redirect_to(login_path) + flash[:notice] = "You must sign in before you can see your ads. Don't have an account? Click Sign Up to create one." + end + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/mailers/.gitkeep b/app/mailers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000..f3d8202 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,3 @@ +class UserMailer < ActionMailer::Base + default from: "from@example.com" +end diff --git a/app/models/.gitkeep b/app/models/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/ad.rb b/app/models/ad.rb new file mode 100644 index 0000000..d2ff538 --- /dev/null +++ b/app/models/ad.rb @@ -0,0 +1,19 @@ +class Ad < ActiveRecord::Base + attr_accessible :title, :description, :city, :state, :views, :sub_cat + + belongs_to :user + has_many :assets + + validates :title, presence: true + validates :description, presence: true + validates :sub_cat, presence: true + + def self.search(search) + if search + where('sub_category LIKE ?', search) + else + find(:all) + end + end + +end diff --git a/app/models/asset.rb b/app/models/asset.rb new file mode 100644 index 0000000..fe25a6f --- /dev/null +++ b/app/models/asset.rb @@ -0,0 +1,5 @@ +class Asset < ActiveRecord::Base + belongs_to :ad + + has_attached_file :image +end diff --git a/app/models/cat.rb b/app/models/cat.rb new file mode 100644 index 0000000..fc11273 --- /dev/null +++ b/app/models/cat.rb @@ -0,0 +1,5 @@ +class Cat < ActiveRecord::Base + attr_accessible :name, :admin, :position + + has_many :sub_cats +end diff --git a/app/models/sub_cat.rb b/app/models/sub_cat.rb new file mode 100644 index 0000000..714ad32 --- /dev/null +++ b/app/models/sub_cat.rb @@ -0,0 +1,3 @@ +class SubCat < ActiveRecord::Base + belongs_to :cat +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..437b0c6 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,14 @@ +class User < ActiveRecord::Base + attr_accessible :login, :email, :password, :password_confirmation, :first_name, :last_name, :street, :city, :state, :zip, :phone + + authenticates_with_sorcery! + + validates :first_name, presence: true + validates :last_name, presence: true + validates :city, presence: true + validates :state, presence: true + validates :zip, presence: true + validates :phone, presence: true + + has_many :ads +end diff --git a/app/views/ads/_ad_summary.slim b/app/views/ads/_ad_summary.slim new file mode 100644 index 0000000..75ab988 --- /dev/null +++ b/app/views/ads/_ad_summary.slim @@ -0,0 +1,7 @@ +.row-fluid.ad-summary + .span3 + .span9 + .title + = link_to a.title, ad_path(a) + .description + = a.description diff --git a/app/views/ads/_form.slim b/app/views/ads/_form.slim new file mode 100644 index 0000000..55933d5 --- /dev/null +++ b/app/views/ads/_form.slim @@ -0,0 +1,14 @@ +.row-fluid + .span4.offset4 + .page-header + h1 Create an Ad + +.row-fluid + .span4.offset4 + = simple_form_for [current_user, @ad], defaults: { input_html: { class: 'span12' } } do |f| + = f.input :title + = f.input :description + = f.input :sub_cat + + .form-actions + = f.button :submit, value: 'Create Ad', class: 'btn btn-primary' diff --git a/app/views/ads/index.slim b/app/views/ads/index.slim new file mode 100644 index 0000000..7ee07fa --- /dev/null +++ b/app/views/ads/index.slim @@ -0,0 +1,2 @@ +- @ads.each do |ad| + = ad.title diff --git a/app/views/ads/new.slim b/app/views/ads/new.slim new file mode 100644 index 0000000..7299279 --- /dev/null +++ b/app/views/ads/new.slim @@ -0,0 +1 @@ += render partial: 'form' diff --git a/app/views/ads/show.slim b/app/views/ads/show.slim new file mode 100644 index 0000000..e69de29 diff --git a/app/views/layouts/application.slim b/app/views/layouts/application.slim new file mode 100644 index 0000000..0448bdc --- /dev/null +++ b/app/views/layouts/application.slim @@ -0,0 +1,38 @@ +doctype html +html + head + title Classie + = stylesheet_link_tag "application", media: "all" + = javascript_include_tag "application" + = csrf_meta_tags + + body + .navbar.navbar-static-top.navbar-inverse + .navbar-inner + .container-fluid + a.btn.btn-navbar data-toggle="collapse" data-target=".nav-collapse" + span class="icon-bar" + span class="icon-bar" + span class="icon-bar" + + a.brand href='/' Classie + + - if current_user + .nav-collapse.collapse + ul.nav + .nav-collapse.collapse + ul.nav.pull-right + li: a.btn.btn-success.btn-small href=new_user_ad_path(current_user) Create Ad + li: a href=user_path(current_user) My Ads + li: a href=signout_path Sign Out + - else + .nav-collapse.collapse + ul.nav.pull-right + li: a href=signin_path Sign In + li: a href=new_user_path Sign Up + + - flash.each do |name, msg| + = content_tag :div, msg, class: "flash alert alert-#{name}" + + .container-fluid + == yield diff --git a/app/views/sessions/new.slim b/app/views/sessions/new.slim new file mode 100644 index 0000000..d4f7446 --- /dev/null +++ b/app/views/sessions/new.slim @@ -0,0 +1,11 @@ +.row-fluid + .span4.offset4 + = form_tag sessions_path do |f| + label Email + = text_field_tag :email, nil, placeholder: "Email", class: 'span12' + + label Password + = password_field_tag :password, nil, placeholder: "Password", class: 'span12' + + .form-actions + = submit_tag "Sign In", class: "btn btn-primary" diff --git a/app/views/shared/_error_block.html.erb b/app/views/shared/_error_block.html.erb new file mode 100644 index 0000000..86873b9 --- /dev/null +++ b/app/views/shared/_error_block.html.erb @@ -0,0 +1,7 @@ +<% if resource.errors.any? %> +
+ <% resource.errors.messages.values.flatten.each do |msg| %> +
<%= msg %>
+ <% end %> +
+<% end %> diff --git a/app/views/users/_form.slim b/app/views/users/_form.slim new file mode 100644 index 0000000..3e9b451 --- /dev/null +++ b/app/views/users/_form.slim @@ -0,0 +1,19 @@ +.row-fluid + .span4.offset4 + .page-header + h1 Create account + +.row-fluid + .span4.offset4 + = simple_form_for @user, defaults: { input_html: { class: 'span12' } } do |f| + = f.input :email + = f.input :password + = f.input :first_name + = f.input :last_name + = f.input :city + = f.input :state + = f.input :zip + = f.input :phone + + .form-actions + = f.button :submit, class: 'btn btn-primary' diff --git a/app/views/users/edit.slim b/app/views/users/edit.slim new file mode 100644 index 0000000..e69de29 diff --git a/app/views/users/new.slim b/app/views/users/new.slim new file mode 100644 index 0000000..7299279 --- /dev/null +++ b/app/views/users/new.slim @@ -0,0 +1 @@ += render partial: 'form' diff --git a/app/views/users/show.slim b/app/views/users/show.slim new file mode 100644 index 0000000..3def582 --- /dev/null +++ b/app/views/users/show.slim @@ -0,0 +1,9 @@ +.row-fluid + .span4.offset4 + .page-header + h1 My Ads + +.row-fluid + .span4.offset4 + - @ads.each do |a| + = render partial: 'ads/ad_summary', locals: { a: a } diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..4be55e8 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Classie::Application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..be361b2 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,68 @@ +require File.expand_path('../boot', __FILE__) + +# Pick the frameworks you want: +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "active_resource/railtie" +require "sprockets/railtie" +# require "rails/test_unit/railtie" + +if defined?(Bundler) + # If you precompile assets before deploying to production, use this line + Bundler.require(*Rails.groups(:assets => %w(development test))) + # If you want your assets lazily compiled in production, use this line + # Bundler.require(:default, :assets, Rails.env) +end + +module Classie + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Custom directories with classes and modules you want to be autoloadable. + # config.autoload_paths += %W(#{config.root}/extras) + + # Only load the plugins named here, in the order given (default is alphabetical). + # :all can be used as a placeholder for all plugins not explicitly named. + # config.plugins = [ :exception_notification, :ssl_requirement, :all ] + + # Activate observers that should always be running. + # config.active_record.observers = :cacher, :garbage_collector, :forum_observer + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Configure the default encoding used in templates for Ruby 1.9. + config.encoding = "utf-8" + + # Configure sensitive parameters which will be filtered from the log file. + config.filter_parameters += [:password] + + # Enable escaping HTML in JSON. + config.active_support.escape_html_entities_in_json = true + + # Use SQL instead of Active Record's schema dumper when creating the database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + + # Enforce whitelist mode for mass assignment. + # This will create an empty whitelist of attributes available for mass-assignment for all models + # in your app. As such, your models will need to explicitly whitelist or blacklist accessible + # parameters by using an attr_accessible or attr_protected declaration. + config.active_record.whitelist_attributes = true + + # Enable the asset pipeline + config.assets.enabled = true + + # Version of your assets, change this if you want to expire all your assets + config.assets.version = '1.0' + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..4489e58 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,6 @@ +require 'rubygems' + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..44a502c --- /dev/null +++ b/config/database.yml @@ -0,0 +1,7 @@ +development: + adapter: postgresql + database: classie_dev + +test: + adapter: postgresql + database: classie_test diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..cda16d9 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the rails application +require File.expand_path('../application', __FILE__) + +# Initialize the rails application +Classie::Application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..f580931 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,43 @@ +Classie::Application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # unicorn + config.logger = Logger.new(STDOUT) + config.logger.level = Logger.const_get( + ENV['LOG_LEVEL'] ? ENV['LOG_LEVEL'].upcase : 'DEBUG' + ) + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger + config.active_support.deprecation = :log + + # Only use best-standards-support built into browsers + config.action_dispatch.best_standards_support = :builtin + + # Raise exception on mass assignment protection for Active Record models + config.active_record.mass_assignment_sanitizer = :strict + + # Log the query plan for queries taking more than this (works + # with SQLite, MySQL, and PostgreSQL) + config.active_record.auto_explain_threshold_in_seconds = 0.5 + + # Do not compress assets + config.assets.compress = false + + # Expands the lines which load the assets + config.assets.debug = true +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..060bf6b --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,73 @@ +Classie::Application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # Code is not reloaded between requests + config.cache_classes = true + + # Full error reports are disabled and caching is turned on + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Disable Rails's static asset server (Apache or nginx will already do this) + config.serve_static_assets = false + + # Compress JavaScripts and CSS + config.assets.compress = true + + # Don't fallback to assets pipeline if a precompiled asset is missed + config.assets.compile = false + + # Generate digests for assets URLs + config.assets.digest = true + + # Defaults to nil and saved in location specified by config.assets.prefix + # config.assets.manifest = YOUR_PATH + + # Specifies the header that your server uses for sending files + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # See everything in the log (default is :info) + # config.log_level = :debug + + # Prepend all log lines with the following tags + # config.log_tags = [ :subdomain, :uuid ] + + # unicorn + config.logger = Logger.new(STDOUT) + config.logger.level = Logger.const_get( + ENV['LOG_LEVEL'] ? ENV['LOG_LEVEL'].upcase : 'INFO' + ) + + # Use a different logger for distributed setups + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server + # config.action_controller.asset_host = "http://assets.example.com" + + # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) + # config.assets.precompile += %w( search.js ) + + # Disable delivery errors, bad email addresses will be ignored + # config.action_mailer.raise_delivery_errors = false + + # Enable threaded mode + # config.threadsafe! + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation can not be found) + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners + config.active_support.deprecation = :notify + + # Log the query plan for queries taking more than this (works + # with SQLite, MySQL, and PostgreSQL) + # config.active_record.auto_explain_threshold_in_seconds = 0.5 +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..2d4320b --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,37 @@ +Classie::Application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Configure static asset server for tests with Cache-Control for performance + config.serve_static_assets = true + config.static_cache_control = "public, max-age=3600" + + # Log error messages when you accidentally call methods on nil + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Raise exception on mass assignment protection for Active Record models + config.active_record.mass_assignment_sanitizer = :strict + + # Print deprecation notices to the stderr + config.active_support.deprecation = :stderr +end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..5d8d9be --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,15 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format +# (all these examples are active by default): +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end +# +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..72aca7e --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf +# Mime::Type.register_alias "text/html", :iphone diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb new file mode 100644 index 0000000..ae24a67 --- /dev/null +++ b/config/initializers/secret_token.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +Classie::Application.config.secret_token = 'ba43a9534dc5fbc788748486b6c3289c4b54e30d04caacc5a781c0a867f9669c7a77fd9513a9a372d28e982a56f44018bcddd1a1b823fcf6f0f0dad369eaff6e' diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..46bf569 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +Classie::Application.config.session_store :cookie_store, key: '_classie_session' + +# Use the database for sessions instead of the cookie-based default, +# which shouldn't be used to store highly confidential information +# (create the session table with "rails generate session_migration") +# Classie::Application.config.session_store :active_record_store diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb new file mode 100644 index 0000000..e3f8d09 --- /dev/null +++ b/config/initializers/simple_form.rb @@ -0,0 +1,142 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + # Wrappers are used by the form builder to generate a + # complete input. You can remove any component from the + # wrapper, change the order or even add your own to the + # stack. The options given below are used to wrap the + # whole input. + config.wrappers :default, :class => :input, + :hint_class => :field_with_hint, :error_class => :field_with_errors do |b| + ## Extensions enabled by default + # Any of these extensions can be disabled for a + # given input by passing: `f.input EXTENSION_NAME => false`. + # You can make any of these extensions optional by + # renaming `b.use` to `b.optional`. + + # Determines whether to use HTML5 (:email, :url, ...) + # and required attributes + b.use :html5 + + # Calculates placeholders automatically from I18n + # You can also pass a string as f.input :placeholder => "Placeholder" + b.use :placeholder + + ## Optional extensions + # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup` + # to the input. If so, they will retrieve the values from the model + # if any exists. If you want to enable the lookup for any of those + # extensions by default, you can change `b.optional` to `b.use`. + + # Calculates maxlength from length validations for string inputs + b.optional :maxlength + + # Calculates pattern from format validations for string inputs + b.optional :pattern + + # Calculates min and max from length validations for numeric inputs + b.optional :min_max + + # Calculates readonly automatically from readonly attributes + b.optional :readonly + + ## Inputs + b.use :label_input + b.use :hint, :wrap_with => { :tag => :span, :class => :hint } + b.use :error, :wrap_with => { :tag => :span, :class => :error } + end + + # The default wrapper to be used by the FormBuilder. + config.default_wrapper = :default + + # Define the way to render check boxes / radio buttons with labels. + # Defaults to :nested for bootstrap config. + # :inline => input + label + # :nested => label > input + config.boolean_style = :nested + + # Default class for buttons + config.button_class = 'btn' + + # Method used to tidy up errors. Specify any Rails Array method. + # :first lists the first message for each field. + # Use :to_sentence to list all errors for each field. + # config.error_method = :first + + # Default tag used for error notification helper. + config.error_notification_tag = :div + + # CSS class to add for error notification helper. + config.error_notification_class = 'alert alert-error' + + # ID to add for error notification helper. + # config.error_notification_id = nil + + # Series of attempts to detect a default label method for collection. + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] + + # Series of attempts to detect a default value method for collection. + # config.collection_value_methods = [ :id, :to_s ] + + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. + # config.collection_wrapper_tag = nil + + # You can define the class to use on all collection wrappers. Defaulting to none. + # config.collection_wrapper_class = nil + + # You can wrap each item in a collection of radio/check boxes with a tag, + # defaulting to :span. Please note that when using :boolean_style = :nested, + # SimpleForm will force this option to be a label. + # config.item_wrapper_tag = :span + + # You can define a class to use in all item wrappers. Defaulting to none. + # config.item_wrapper_class = nil + + # How the label text should be generated altogether with the required text. + # config.label_text = lambda { |label, required| "#{required} #{label}" } + + # You can define the class to use on all labels. Default is nil. + config.label_class = 'control-label' + + # You can define the class to use on all forms. Default is simple_form. + # config.form_class = :simple_form + + # You can define which elements should obtain additional classes + # config.generate_additional_classes_for = [:wrapper, :label, :input] + + # Whether attributes are required by default (or not). Default is true. + # config.required_by_default = true + + # Tell browsers whether to use default HTML5 validations (novalidate option). + # Default is enabled. + config.browser_validations = false + + # Collection of methods to detect if a file type was given. + # config.file_methods = [ :mounted_as, :file?, :public_filename ] + + # Custom mappings for input types. This should be a hash containing a regexp + # to match as key, and the input type that will be used when the field name + # matches the regexp as value. + # config.input_mappings = { /count/ => :integer } + + # Custom wrappers for input types. This should be a hash containing an input + # type as key and the wrapper that will be used for all inputs with specified type. + # config.wrapper_mappings = { :string => :prepend } + + # Default priority for time_zone inputs. + # config.time_zone_priority = nil + + # Default priority for country inputs. + # config.country_priority = nil + + # Default size for text inputs. + # config.default_input_size = 50 + + # When false, do not use translations for labels. + # config.translate_labels = true + + # Automatically discover new inputs in Rails' autoload path. + # config.inputs_discovery = true + + # Cache SimpleForm inputs discovery + # config.cache_discovery = !Rails.env.development? +end diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb new file mode 100644 index 0000000..1a22967 --- /dev/null +++ b/config/initializers/simple_form_bootstrap.rb @@ -0,0 +1,45 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b| + b.use :html5 + b.use :placeholder + b.use :label + b.wrapper :tag => 'div', :class => 'controls' do |ba| + ba.use :input + ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } + end + end + + config.wrappers :prepend, :tag => 'div', :class => "control-group", :error_class => 'error' do |b| + b.use :html5 + b.use :placeholder + b.use :label + b.wrapper :tag => 'div', :class => 'controls' do |input| + input.wrapper :tag => 'div', :class => 'input-prepend' do |prepend| + prepend.use :input + end + input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' } + input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + end + end + + config.wrappers :append, :tag => 'div', :class => "control-group", :error_class => 'error' do |b| + b.use :html5 + b.use :placeholder + b.use :label + b.wrapper :tag => 'div', :class => 'controls' do |input| + input.wrapper :tag => 'div', :class => 'input-append' do |append| + append.use :input + end + input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' } + input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + end + end + + # Wrappers for forms and inputs using the Twitter Bootstrap toolkit. + # Check the Bootstrap docs (http://twitter.github.com/bootstrap) + # to learn about the different styles for forms and inputs, + # buttons and other elements. + config.default_wrapper = :bootstrap +end diff --git a/config/initializers/sorcery.rb b/config/initializers/sorcery.rb new file mode 100644 index 0000000..95db773 --- /dev/null +++ b/config/initializers/sorcery.rb @@ -0,0 +1,437 @@ +# The first thing you need to configure is which modules you need in your app. +# The default is nothing which will include only core features (password encryption, login/logout). +# Available submodules are: :user_activation, :http_basic_auth, :remember_me, +# :reset_password, :session_timeout, :brute_force_protection, :activity_logging, :external +Rails.application.config.sorcery.submodules = [:reset_password, :remember_me, :http_basic_auth, :activity_logging] + +# Here you can configure each submodule's features. +Rails.application.config.sorcery.configure do |config| + # -- core -- + # What controller action to call for non-authenticated users. You can also + # override the 'not_authenticated' method of course. + # Default: `:not_authenticated` + # + # config.not_authenticated_action = + + + # When a non logged in user tries to enter a page that requires login, save + # the URL he wanted to reach, and send him there after login, using 'redirect_back_or_to'. + # Default: `true` + # + # config.save_return_to_url = + + + # Set domain option for cookies; Useful for remember_me submodule. + # Default: `nil` + # + # config.cookie_domain = + + + # -- session timeout -- + # How long in seconds to keep the session alive. + # Default: `3600` + # + # config.session_timeout = + + + # Use the last action as the beginning of session timeout. + # Default: `false` + # + # config.session_timeout_from_last_action = + + + # -- http_basic_auth -- + # What realm to display for which controller name. For example {"My App" => "Application"} + # Default: `{"application" => "Application"}` + # + # config.controller_to_realm_map = + + + # -- activity logging -- + # will register the time of last user login, every login. + # Default: `true` + # + # config.register_login_time = + + + # will register the time of last user logout, every logout. + # Default: `true` + # + # config.register_logout_time = + + + # will register the time of last user action, every action. + # Default: `true` + # + # config.register_last_activity_time = + + + # -- external -- + # What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid] . + # Default: `[]` + # + # config.external_providers = + + + # You can change it by your local ca_file. i.e. '/etc/pki/tls/certs/ca-bundle.crt' + # Path to ca_file. By default use a internal ca-bundle.crt. + # Default: `'path/to/ca_file'` + # + # config.ca_file = + + + # For information about LinkedIn API: + # - user info fields go to https://developer.linkedin.com/documents/profile-fields + # - access permissions go to https://developer.linkedin.com/documents/authentication#granting + # + # config.linkedin.key = "" + # config.linkedin.secret = "" + # config.linkedin.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=linkedin" + # config.linkedin.user_info_fields = ['first-name', 'last-name'] + # config.linkedin.user_info_mapping = {first_name: "firstName", last_name: "lastName"} + # config.linkedin.access_permissions = ['r_basicprofile'] + # + # + # For information about XING API: + # - user info fields go to https://dev.xing.com/docs/get/users/me + # + # config.xing.key = "" + # config.xing.secret = "" + # config.xing.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=xing" + # config.xing.user_info_mapping = {first_name: "first_name", last_name: "last_name"} + # + # + # Twitter wil not accept any requests nor redirect uri containing localhost, + # make sure you use 0.0.0.0:3000 to access your app in development + # + # config.twitter.key = "" + # config.twitter.secret = "" + # config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter" + # config.twitter.user_info_mapping = {:email => "screen_name"} + # + # config.facebook.key = "" + # config.facebook.secret = "" + # config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook" + # config.facebook.user_info_mapping = {:email => "name"} + # config.facebook.access_permissions = ["email", "publish_stream"] + # + # config.github.key = "" + # config.github.secret = "" + # config.github.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=github" + # config.github.user_info_mapping = {:email => "name"} + # + # config.google.key = "" + # config.google.secret = "" + # config.google.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=google" + # config.google.user_info_mapping = {:email => "email", :username => "name"} + # + # config.vk.key = "" + # config.vk.secret = "" + # config.vk.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=vk" + # config.vk.user_info_mapping = {:login => "domain", :name => "full_name"} + # + # To use liveid in development mode you have to replace mydomain.com with + # a valid domain even in development. To use a valid domain in development + # simply add your domain in your /etc/hosts file in front of 127.0.0.1 + # + # config.liveid.key = "" + # config.liveid.secret = "" + # config.liveid.callback_url = "http://mydomain.com:3000/oauth/callback?provider=liveid" + # config.liveid.user_info_mapping = {:username => "name"} + + + # --- user config --- + config.user_config do |user| + # -- core -- + # specify username attributes, for example: [:username, :email]. + # Default: `[:username]` + # + user.username_attribute_names = [:email] + + + # change *virtual* password attribute, the one which is used until an encrypted one is generated. + # Default: `:password` + # + # user.password_attribute_name = + + + # downcase the username before trying to authenticate, default is false + # Default: `false` + # + # user.downcase_username_before_authenticating = + + + # change default email attribute. + # Default: `:email` + # + # user.email_attribute_name = + + + # change default crypted_password attribute. + # Default: `:crypted_password` + # + # user.crypted_password_attribute_name = + + + # what pattern to use to join the password with the salt + # Default: `""` + # + # user.salt_join_token = + + + # change default salt attribute. + # Default: `:salt` + # + # user.salt_attribute_name = + + + # how many times to apply encryption to the password. + # Default: `nil` + # + # user.stretches = + + + # encryption key used to encrypt reversible encryptions such as AES256. + # WARNING: If used for users' passwords, changing this key will leave passwords undecryptable! + # Default: `nil` + # + # user.encryption_key = + + + # use an external encryption class. + # Default: `nil` + # + # user.custom_encryption_provider = + + + # encryption algorithm name. See 'encryption_algorithm=' for available options. + # Default: `:bcrypt` + # + # user.encryption_algorithm = + + + # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI. + # Default: `false` + # + # user.subclasses_inherit_config = + + + # -- remember_me -- + # allow the remember_me cookie to settable through AJAX + # Default: `true` + # + # user.remember_me_httponly = + + # How long in seconds the session length will be + # Default: `604800` + # + # user.remember_me_for = + + + # -- user_activation -- + # the attribute name to hold activation state (active/pending). + # Default: `:activation_state` + # + # user.activation_state_attribute_name = + + + # the attribute name to hold activation code (sent by email). + # Default: `:activation_token` + # + # user.activation_token_attribute_name = + + + # the attribute name to hold activation code expiration date. + # Default: `:activation_token_expires_at` + # + # user.activation_token_expires_at_attribute_name = + + + # how many seconds before the activation code expires. nil for never expires. + # Default: `nil` + # + # user.activation_token_expiration_period = + + + # your mailer class. Required. + # Default: `nil` + # + # user.user_activation_mailer = + + + # when true sorcery will not automatically + # email activation details and allow you to + # manually handle how and when email is sent. + # Default: `false` + # + # user.activation_mailer_disabled = + + + # activation needed email method on your mailer class. + # Default: `:activation_needed_email` + # + # user.activation_needed_email_method_name = + + + # activation success email method on your mailer class. + # Default: `:activation_success_email` + # + # user.activation_success_email_method_name = + + + # do you want to prevent or allow users that did not activate by email to login? + # Default: `true` + # + # user.prevent_non_active_users_to_login = + + + # -- reset_password -- + # reset password code attribute name. + # Default: `:reset_password_token` + # + # user.reset_password_token_attribute_name = + + + # expires at attribute name. + # Default: `:reset_password_token_expires_at` + # + # user.reset_password_token_expires_at_attribute_name = + + + # when was email sent, used for hammering protection. + # Default: `:reset_password_email_sent_at` + # + # user.reset_password_email_sent_at_attribute_name = + + + # mailer class. Needed. + # Default: `nil` + # + user.reset_password_mailer = UserMailer + + + # reset password email method on your mailer class. + # Default: `:reset_password_email` + # + # user.reset_password_email_method_name = + + + # when true sorcery will not automatically + # email password reset details and allow you to + # manually handle how and when email is sent + # Default: `false` + # + # user.reset_password_mailer_disabled = + + + # how many seconds before the reset request expires. nil for never expires. + # Default: `nil` + # + # user.reset_password_expiration_period = + + + # hammering protection, how long to wait before allowing another email to be sent. + # Default: `5 * 60` + # + # user.reset_password_time_between_emails = + + + # -- brute_force_protection -- + # Failed logins attribute name. + # Default: `:failed_logins_count` + # + # user.failed_logins_count_attribute_name = + + + # This field indicates whether user is banned and when it will be active again. + # Default: `:lock_expires_at` + # + # user.lock_expires_at_attribute_name = + + + # How many failed logins allowed. + # Default: `50` + # + # user.consecutive_login_retries_amount_limit = + + + # How long the user should be banned. in seconds. 0 for permanent. + # Default: `60 * 60` + # + # user.login_lock_time_period = + + # Unlock token attribute name + # Default: `:unlock_token` + # + # user.unlock_token_attribute_name = + + # Unlock token mailer method + # Default: `:send_unlock_token_email` + # + # user.unlock_token_email_method_name = + + # when true sorcery will not automatically + # send email with unlock token + # Default: `false` + # + # user.unlock_token_mailer_disabled = true + + # Unlock token mailer class + # Default: `nil` + # + # user.unlock_token_mailer = UserMailer + + # -- activity logging -- + # Last login attribute name. + # Default: `:last_login_at` + # + # user.last_login_at_attribute_name = + + + # Last logout attribute name. + # Default: `:last_logout_at` + # + # user.last_logout_at_attribute_name = + + + # Last activity attribute name. + # Default: `:last_activity_at` + # + # user.last_activity_at_attribute_name = + + + # How long since last activity is he user defined logged out? + # Default: `10 * 60` + # + # user.activity_timeout = + + + # -- external -- + # Class which holds the various external provider data for this user. + # Default: `nil` + # + # user.authentications_class = + + + # User's identifier in authentications class. + # Default: `:user_id` + # + # user.authentications_user_id_attribute_name = + + + # Provider's identifier in authentications class. + # Default: `:provider` + # + # user.provider_attribute_name = + + + # User's external unique identifier in authentications class. + # Default: `:uid` + # + # user.provider_uid_attribute_name = + end + + # This line must come after the 'user config' block. + # Define which model authenticates with sorcery. + config.user_class = "User" +end diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..999df20 --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# Disable root element in JSON by default. +ActiveSupport.on_load(:active_record) do + self.include_root_in_json = false +end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..179c14c --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,5 @@ +# Sample localization file for English. Add more files in this directory for other locales. +# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. + +en: + hello: "Hello world" diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml new file mode 100644 index 0000000..0df11fe --- /dev/null +++ b/config/locales/simple_form.en.yml @@ -0,0 +1,26 @@ +en: + simple_form: + "yes": 'Yes' + "no": 'No' + required: + text: 'required' + mark: '*' + # You can uncomment the line below if you need to overwrite the whole required html. + # When using html, text and mark won't be used. + # html: '*' + error_notification: + default_message: "Please review the problems below:" + # Labels and hints examples + # labels: + # defaults: + # password: 'Password' + # user: + # new: + # email: 'E-mail to sign in.' + # edit: + # email: 'E-mail.' + # hints: + # defaults: + # username: 'User name to sign in.' + # password: 'No special characters, please.' + diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..09dab94 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,15 @@ +Classie::Application.routes.draw do + + resources :ads + + resources :users do + resources :ads + end + + resources :sessions + get 'signin' => 'sessions#new', as: 'signin' + get 'signout' => 'sessions#destroy', as: 'signout' + + root to: 'ads#index' + +end diff --git a/config/unicorn.rb b/config/unicorn.rb new file mode 100644 index 0000000..5ebe0d3 --- /dev/null +++ b/config/unicorn.rb @@ -0,0 +1,24 @@ +if ENV['RAILS_ENV'] == 'development' + worker_processes 1 +else + worker_processes 4 +end + +timeout 30 +preload_app true + +before_fork do |server, worker| + if defined?(ActiveRecord::Base) + ActiveRecord::Base.connection.disconnect! + Rails.logger.info('Disconnected from ActiveRecord') + end + sleep 1 +end + +after_fork do |server, worker| + if defined?(ActiveRecord::Base) + ActiveRecord::Base.establish_connection + Rails.logger.info('Connected to ActiveRecord') + end +end + diff --git a/db/migrate/20130711205743_sorcery_core.rb b/db/migrate/20130711205743_sorcery_core.rb new file mode 100644 index 0000000..e9e68bf --- /dev/null +++ b/db/migrate/20130711205743_sorcery_core.rb @@ -0,0 +1,14 @@ +class SorceryCore < ActiveRecord::Migration + def self.up + create_table :users do |t| + t.string :email, :null => false # if you use this field as a username, you might want to make it :null => false. + t.string :crypted_password, :default => nil + t.string :salt, :default => nil + t.timestamps + end + end + + def self.down + drop_table :users + end +end diff --git a/db/migrate/20130711205744_sorcery_reset_password.rb b/db/migrate/20130711205744_sorcery_reset_password.rb new file mode 100644 index 0000000..3095886 --- /dev/null +++ b/db/migrate/20130711205744_sorcery_reset_password.rb @@ -0,0 +1,17 @@ +class SorceryResetPassword < ActiveRecord::Migration + def self.up + add_column :users, :reset_password_token, :string, :default => nil + add_column :users, :reset_password_token_expires_at, :datetime, :default => nil + add_column :users, :reset_password_email_sent_at, :datetime, :default => nil + + add_index :users, :reset_password_token + end + + def self.down + remove_index :users, :reset_password_token + + remove_column :users, :reset_password_email_sent_at + remove_column :users, :reset_password_token_expires_at + remove_column :users, :reset_password_token + end +end \ No newline at end of file diff --git a/db/migrate/20130711205745_sorcery_remember_me.rb b/db/migrate/20130711205745_sorcery_remember_me.rb new file mode 100644 index 0000000..22d9579 --- /dev/null +++ b/db/migrate/20130711205745_sorcery_remember_me.rb @@ -0,0 +1,15 @@ +class SorceryRememberMe < ActiveRecord::Migration + def self.up + add_column :users, :remember_me_token, :string, :default => nil + add_column :users, :remember_me_token_expires_at, :datetime, :default => nil + + add_index :users, :remember_me_token + end + + def self.down + remove_index :users, :remember_me_token + + remove_column :users, :remember_me_token_expires_at + remove_column :users, :remember_me_token + end +end \ No newline at end of file diff --git a/db/migrate/20130711205746_sorcery_activity_logging.rb b/db/migrate/20130711205746_sorcery_activity_logging.rb new file mode 100644 index 0000000..d863c50 --- /dev/null +++ b/db/migrate/20130711205746_sorcery_activity_logging.rb @@ -0,0 +1,19 @@ +class SorceryActivityLogging < ActiveRecord::Migration + def self.up + add_column :users, :last_login_at, :datetime, :default => nil + add_column :users, :last_logout_at, :datetime, :default => nil + add_column :users, :last_activity_at, :datetime, :default => nil + add_column :users, :last_login_from_ip_address, :string, :default => nil + + add_index :users, [:last_logout_at, :last_activity_at] + end + + def self.down + remove_index :users, [:last_logout_at, :last_activity_at] + + remove_column :users, :last_login_from_ip_address + remove_column :users, :last_activity_at + remove_column :users, :last_logout_at + remove_column :users, :last_login_at + end +end \ No newline at end of file diff --git a/db/migrate/20130711205852_create_delayed_jobs.rb b/db/migrate/20130711205852_create_delayed_jobs.rb new file mode 100644 index 0000000..e784160 --- /dev/null +++ b/db/migrate/20130711205852_create_delayed_jobs.rb @@ -0,0 +1,22 @@ +class CreateDelayedJobs < ActiveRecord::Migration + def self.up + create_table :delayed_jobs, :force => true do |table| + table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue + table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually. + table.text :handler # YAML-encoded string of the object that will do work + table.text :last_error # reason for last failure (See Note below) + table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. + table.datetime :locked_at # Set when a client is working on this object + table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) + table.string :locked_by # Who is working on this object (if locked) + table.string :queue # The name of the queue this job is in + table.timestamps + end + + add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority' + end + + def self.down + drop_table :delayed_jobs + end +end diff --git a/db/migrate/20130712230139_create_ads.rb b/db/migrate/20130712230139_create_ads.rb new file mode 100644 index 0000000..e916ff2 --- /dev/null +++ b/db/migrate/20130712230139_create_ads.rb @@ -0,0 +1,16 @@ +class CreateAds < ActiveRecord::Migration + def change + create_table :ads do |t| + t.string :title + t.text :description + t.integer :user_id + t.string :price + t.string :city + t.string :state + t.string :sub_cat + t.integer :views + + t.timestamps + end + end +end diff --git a/db/migrate/20130712230451_add_name_and_address_to_user.rb b/db/migrate/20130712230451_add_name_and_address_to_user.rb new file mode 100644 index 0000000..c288b98 --- /dev/null +++ b/db/migrate/20130712230451_add_name_and_address_to_user.rb @@ -0,0 +1,10 @@ +class AddNameAndAddressToUser < ActiveRecord::Migration + def change + add_column :users, :first_name, :string + add_column :users, :last_name, :string + add_column :users, :city, :string + add_column :users, :state, :string + add_column :users, :zip, :string + add_column :users, :phone, :string + end +end diff --git a/db/migrate/20130715154627_create_cats.rb b/db/migrate/20130715154627_create_cats.rb new file mode 100644 index 0000000..b2b00a8 --- /dev/null +++ b/db/migrate/20130715154627_create_cats.rb @@ -0,0 +1,11 @@ +class CreateCats < ActiveRecord::Migration + def change + create_table :cats do |t| + t.string :name + t.boolean :admin + t.integer :position + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..18f967e --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,80 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20130715154627) do + + create_table "ads", :force => true do |t| + t.string "title" + t.text "description" + t.integer "user_id" + t.string "price" + t.string "city" + t.string "state" + t.string "sub_cat" + t.integer "views" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "cats", :force => true do |t| + t.string "name" + t.boolean "admin" + t.integer "position" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "delayed_jobs", :force => true do |t| + t.integer "priority", :default => 0 + t.integer "attempts", :default => 0 + t.text "handler" + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" + + create_table "users", :force => true do |t| + t.string "email", :null => false + t.string "crypted_password" + t.string "salt" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reset_password_token" + t.datetime "reset_password_token_expires_at" + t.datetime "reset_password_email_sent_at" + t.string "remember_me_token" + t.datetime "remember_me_token_expires_at" + t.datetime "last_login_at" + t.datetime "last_logout_at" + t.datetime "last_activity_at" + t.string "last_login_from_ip_address" + t.string "first_name" + t.string "last_name" + t.string "city" + t.string "state" + t.string "zip" + t.string "phone" + end + + add_index "users", ["last_logout_at", "last_activity_at"], :name => "index_users_on_last_logout_at_and_last_activity_at" + add_index "users", ["remember_me_token"], :name => "index_users_on_remember_me_token" + add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token" + +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..4edb1e8 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) +# Mayor.create(name: 'Emanuel', city: cities.first) diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP new file mode 100644 index 0000000..fe41f5c --- /dev/null +++ b/doc/README_FOR_APP @@ -0,0 +1,2 @@ +Use this README file to introduce your application and point to useful places in the API for learning more. +Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. diff --git a/lib/assets/.gitkeep b/lib/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/lib/generators/print/USAGE b/lib/generators/print/USAGE new file mode 100644 index 0000000..6169b83 --- /dev/null +++ b/lib/generators/print/USAGE @@ -0,0 +1,9 @@ +Description: + Set up app + +Example: + rails generate print new_app_name + + Right now this will only change files in the app + that contain blue_print or BluePrint + to new_app_name or NewAppName diff --git a/lib/generators/print/print_generator.rb b/lib/generators/print/print_generator.rb new file mode 100644 index 0000000..dc87a23 --- /dev/null +++ b/lib/generators/print/print_generator.rb @@ -0,0 +1,24 @@ +class PrintGenerator < Rails::Generators::Base + source_root File.expand_path('../templates', __FILE__) + + argument :new_app_name, type: :string, default: 'blue_print' + + def rename + root = Rails.root + files = [File.expand_path('Rakefile', root),File.expand_path('Readme.md', root),File.expand_path('config.ru', root),File.expand_path('config/application.rb', root),File.expand_path('config/database.yml', root),File.expand_path('config/environment.rb', root),File.expand_path('config/environments/test.rb', root),File.expand_path('config/environments/development.rb', root),File.expand_path('config/environments/production.rb', root),File.expand_path('config/initializers/session_store.rb', root),File.expand_path('config/initializers/secret_token.rb', root),File.expand_path('config/routes.rb', root)] + puts 'Changing names in files.' + files.each do |path| + file = File.read(path) + new_file = file.gsub(/(blue_print|BluePrint)/) do |match| + case match + when 'blue_print' + new_app_name + when 'BluePrint' + new_app_name.camelize + end + end + File.open(path, 'w') { |file| file.puts new_file } + end + puts 'Names all changed' + end +end diff --git a/lib/tasks/.gitkeep b/lib/tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb new file mode 100644 index 0000000..201a069 --- /dev/null +++ b/lib/templates/erb/scaffold/_form.html.erb @@ -0,0 +1,13 @@ +<%%= simple_form_for(@<%= singular_table_name %>) do |f| %> + <%%= f.error_notification %> + +
+ <%- attributes.each do |attribute| -%> + <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %> + <%- end -%> +
+ +
+ <%%= f.button :submit %> +
+<%% end %> diff --git a/log/.gitkeep b/log/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..9a48320 --- /dev/null +++ b/public/404.html @@ -0,0 +1,26 @@ + + + + The page you were looking for doesn't exist (404) + + + + + +
+

The page you were looking for doesn't exist.

+

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

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

The change you wanted was rejected.

+

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

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

We're sorry, but something went wrong.

+
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..085187f --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-Agent: * +# Disallow: / diff --git a/script/delayed_job b/script/delayed_job new file mode 100755 index 0000000..edf1959 --- /dev/null +++ b/script/delayed_job @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) +require 'delayed/command' +Delayed::Command.new(ARGV).daemonize diff --git a/script/rails b/script/rails new file mode 100755 index 0000000..f8da2cf --- /dev/null +++ b/script/rails @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands' diff --git a/test/fixtures/ads.yml b/test/fixtures/ads.yml new file mode 100644 index 0000000..a7c2851 --- /dev/null +++ b/test/fixtures/ads.yml @@ -0,0 +1,22 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + title: MyString + description: MyText + user_id: 1 + price: MyString + city: MyString + state: MyString + sub_cat: MyString + views: 1 + +two: + title: MyString + description: MyText + user_id: 1 + price: MyString + city: MyString + state: MyString + sub_cat: MyString + views: 1 diff --git a/test/fixtures/cats.yml b/test/fixtures/cats.yml new file mode 100644 index 0000000..fa14f1a --- /dev/null +++ b/test/fixtures/cats.yml @@ -0,0 +1,12 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + name: MyString + admin: false + position: 1 + +two: + name: MyString + admin: false + position: 1 diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..8787f86 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,12 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb new file mode 100644 index 0000000..5f65b81 --- /dev/null +++ b/test/mailers/user_mailer_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class UserMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/ad_test.rb b/test/models/ad_test.rb new file mode 100644 index 0000000..fd72e0a --- /dev/null +++ b/test/models/ad_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class AdTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/cat_test.rb b/test/models/cat_test.rb new file mode 100644 index 0000000..c3c285c --- /dev/null +++ b/test/models/cat_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class CatTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..5c07f49 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/vendor/assets/javascripts/.gitkeep b/vendor/assets/javascripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/stylesheets/.gitkeep b/vendor/assets/stylesheets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/plugins/.gitkeep b/vendor/plugins/.gitkeep new file mode 100644 index 0000000..e69de29