# App Template # By Matt Polito # Link to local copy of edge rails rake('rails:freeze:gems') # Delete unnecessary files run "rm README" run "rm public/index.html" run "rm public/favicon.ico" run "rm public/robots.txt" run "rm -f public/javascripts/*" # # Download JQuery # inside('public/javascripts') do # run "curl -L http://jqueryjs.googlecode.com/files/jquery-1.3.min.js > jquery.js" # run "curl -d 'version=1.6rc5&compression=jsmin&files%5B%5D=ui.core.js&files%5B%5D=ui.draggable.js&files%5B%5D=ui.droppable.js&files%5B%5D=ui.resizable.js&files%5B%5D=ui.selectable.js&files%5B%5D=ui.sortable.js&files%5B%5D=ui.accordion.js&files%5B%5D=ui.dialog.js&files%5B%5D=ui.slider.js&files%5B%5D=ui.tabs.js&files%5B%5D=ui.datepicker.js&files%5B%5D=ui.progressbar.js&files%5B%5D=effects.core.js&files%5B%5D=effects.blind.js&files%5B%5D=effects.bounce.js&files%5B%5D=effects.clip.js&files%5B%5D=effects.drop.js&files%5B%5D=effects.explode.js&files%5B%5D=effects.fold.js&files%5B%5D=effects.highlight.js&files%5B%5D=effects.pulsate.js&files%5B%5D=effects.scale.js&files%5B%5D=effects.shake.js&files%5B%5D=effects.slide.js&files%5B%5D=effects.transfer.js' http://ui.jquery.com/actions/download_builder.php -L > jqueryui.zip" # run "curl -L http://ui.jquery.com/applications/themeroller/download.php?href=/applications/themeroller/css/parseTheme.css.php?ctl=themeroller > theme.zip" # run "unzip theme.zip -d jquery-ui-theme" # run "rm theme.zip" # run "unzip jqueryui.zip" # run "rm jqueryui.zip" # run "rm -rf ui" # run "find . -name \"jquery-ui*.js\" | xargs -I xxx mv xxx jquery-ui.js" # end # Set up git repository git :init git :add => '.' # Copy database.yml for distribution use run "cp config/database.yml config/database.yml.example" # Set up .gitignore files run "touch tmp/.gitignore log/.gitignore" run %{find . -type d -empty | grep -v ".git" | grep -v "tmp" | xargs -I xxx touch xxx/.gitignore} file '.gitignore', <<-END .DS_Store log/*.log tmp/**/* config/database.yml db/*.sqlite3 END # Set up session store initializer initializer 'session_store.rb', <<-END ActionController::Base.session = { :session_key => '_#{(1..6).map { |x| (65 + rand(26)).chr }.join}_session', :secret => '#{(1..40).map { |x| (65 + rand(26)).chr }.join}' } ActionController::Base.session_store = :active_record_store END # Install all plugins plugin 'jrails', :git => 'git://github.com/aaronchi/jrails.git', :submodule => true plugin 'open_id_authentication', :git => 'git://github.com/rails/open_id_authentication.git', :submodule => true plugin 'seed-fu', :git => 'git://github.com/mbleigh/seed-fu.git', :submodule => true # Install all gems gem 'authlogic', :version => '>= 1.4.0' gem 'gravtastic', :version => '>= 2.0.0' gem 'haml', :version => '>= 2.0.7' gem 'ruby-openid', :lib => 'openid' gem 'settingslogic' # gem 'mislav-will_paginate', :version => '~> 2.2.3', :lib => 'will_paginate', :source => 'http://gems.github.com' rake('gems:install', :sudo => true) rake('gems:unpack') # Create DB rake('db:create') # Initialize submodules git :submodule => "init" # Commit all work so far to the repository git :add => '.' git :commit => "-a -m 'Initial commit'" # Generate Authlogic code generate("session", "user_session") generate("controller", "user_sessions") generate("scaffold", "user login:string crypted_password:string persistence_token:string login_count:integer last_request_at:datetime last_login_at:datetime current_login_at:datetime last_login_ip:string current_login_ip:string") # Remove auto generated users migration run "rm db/migrate/*_create_users.rb" # Create new users migration with all needed fields file "db/migrate/#{Time.now.strftime("%Y%m%d%H%M%S")}_create_users.rb", <<-END class CreateUsers < ActiveRecord::Migration def self.up create_table "users", :force => true do |t| t.string "login" t.string "crypted_password" t.string "password_salt" t.string "persistence_token" t.integer "login_count" t.datetime "last_request_at" t.datetime "last_login_at" t.datetime "current_login_at" t.string "last_login_ip" t.string "current_login_ip" t.string "openid_identifier" t.string "perishable_token", :default => "", :null => false t.string "email", :default => "", :null => false t.timestamps end add_index "users", ["email"], :name => "index_users_on_email" add_index "users", ["openid_identifier"], :name => "index_users_on_openid_identifier" add_index "users", ["perishable_token"], :name => "index_users_on_perishable_token" end def self.down drop_table :users end end END # Set up sessions, RSpec, user model, OpenID, etc, and run migrations rake('db:sessions:create') # generate("roles", "Role User") rake('open_id_authentication:db:create') rake('db:migrate:reset') # Remove unnecessary erb files run "rm views/layouts/users.html.erb" run "rm views/users/edit.html.erb" run "rm views/users/new.html.erb" run "rm views/users/show.html.erb" ### Config ### file 'config/routes.rb', <<-END ActionController::Routing::Routes.draw do |map| # The priority is based upon order of creation: first created -> highest priority. # Sample of regular route: # map.connect 'products/:id', :controller => 'catalog', :action => 'view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' # This route can be invoked with purchase_url(:id => product.id) map.login '/login', :controller => 'user_sessions', :action => 'new' map.logout '/logout', :controller => 'user_sessions', :action => 'destroy' # Sample resource route (maps HTTP verbs to controller actions automatically): # map.resources :products # Sample resource route with options: # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } # Sample resource route with sub-resources: # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller # Sample resource route with more complex sub-resources # map.resources :products do |products| # products.resources :comments # products.resources :sales, :collection => { :recent => :get } # end # Sample resource route within a namespace: # map.namespace :admin do |admin| # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) # admin.resources :products # end map.resources :users map.resource :account, :controller => :users map.resource :user_sessions # You can have the root of your site routed with map.root -- just remember to delete public/index.html. # map.root :controller => "welcome" map.root :controller => 'user_sessions', :action => 'new' # See how all your routes lay out with "rake routes" # Install the default routes as the lowest priority. # Note: These default routes make all actions in every controller accessible via GET requests. You should # consider removing the them or commenting them out if you're using named routes and resources. map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end END ### Controllers ### file 'app/controllers/application_controller.rb', <<-END class ApplicationController < ActionController::Base helper :all helper_method :current_user_session, :current_user filter_parameter_logging :password, :password_confirmation private def current_user_session return @current_user_session if defined?(@current_user_session) @current_user_session = UserSession.find end def current_user return @current_user if defined?(@current_user) @current_user = current_user_session && current_user_session.record end def require_user unless current_user store_location flash[:notice] = "You must be logged in to access this page" redirect_to new_user_session_url return false end end def require_no_user if current_user store_location flash[:notice] = "You must be logged out to access this page" redirect_to account_url return false end end def store_location session[:return_to] = request.request_uri end def redirect_back_or_default(default) redirect_to(session[:return_to] || default) session[:return_to] = nil end end END file 'app/controllers/users_controller.rb', <<-END class UsersController < ApplicationController before_filter :require_no_user, :only => [:new, :create] before_filter :require_user, :only => [:show, :edit, :update] def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = "Account registered!" redirect_back_or_default account_url else render :action => :new end end def show @user = @current_user end def edit @user = @current_user end def update @user = @current_user # makes our views "cleaner" and more consistent if @user.update_attributes(params[:user]) flash[:notice] = "Account updated!" redirect_to account_url else render :action => :edit end end end END file 'app/controllers/user_sessions_controller.rb', <<-END class UserSessionsController < ApplicationController before_filter :require_no_user, :only => [:new, :create] before_filter :require_user, :only => :destroy def new @user_session = UserSession.new end def create @user_session = UserSession.new(params[:user_session]) if @user_session.save flash[:notice] = "Login successful!" redirect_back_or_default account_url else render :action => :new end end def destroy current_user_session.destroy flash[:notice] = "Logout successful!" redirect_back_or_default new_user_session_url end end END ### Models ### file 'app/models/user.rb', <<-END class User < ActiveRecord::Base acts_as_authentic def deliver_password_reset_instructions! reset_perishable_token! Notifier.deliver_password_reset_instructions(self) end end END file 'app/models/user_session.rb', <<-END class UserSession < Authlogic::Session::Base attr_accessor :openid_identifier def authenticating_with_openid? !openid_identifier.blank? || controller.params[:open_id_complete] end def save(&block) if authenticating_with_openid? raise ArgumentError.new("You must supply a block to authenticate with OpenID") unless block_given? controller.send(:authenticate_with_open_id, openid_identifier) do |result, openid_identifier| if !result.successful? errors.add_to_base(result.message) yield false return end record = klass.find_by_openid_identifier(openid_identifier) if !record errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?") yield false return end self.unauthorized_record = record super end else super end end end END ### Helpers ### file 'app/helpers/application_helper.rb', <<-END # Methods added to this helper will be available to all templates in the application. module ApplicationHelper def display_none_unless_openid_is_blank(user_session) user_session.openid_identifier.blank? ? {} : { :style => 'display: none;' } end def display_none_if_openid_is_blank(user_session) user_session.openid_identifier.blank? ? { :style => 'display: none;' } : {} end def is_new_action? controller.action_name == 'new' end end END ### Views ### # Notifier file 'app/views/notifier/password_reset_instructions.html.haml', <<-END A request to reset your password has been made. If you did not make this request, simply ignore this email. If you did make this request just click the link below: = @edit_password_reset_url If the above URL does not work try copying and pasting it into your browser. If you continue to have problem please feel free to contact us. END # Password Resets file 'app/views/password_resets/edit.html.haml', <<-END %h1 Change My Password - form_for @user, :url => password_reset_path, :method => :put do |f| = f.error_messages = f.label :password %br = f.password_field :password %br %br = f.label :password_confirmation %br = f.password_field :password_confirmation %br %br = f.submit "Update my password and log me in" END file 'app/views/password_resets/new.html.haml', <<-END %h1 Forgot Password %p Fill out the form below and instructions to reset your password will be emailed to you: - form_tag password_resets_path do %label Email: %p= text_field_tag "email" %p= submit_tag "Reset my password" END # User Sessions file 'app/views/user_sessions/new.html.haml', <<-END %h1 Login - form_for @user_session, :url => user_sessions_path do |f| = f.error_messages #login_container{ display_none_unless_openid_is_blank(@user_session) } %p = f.label :login (or = link_to_function "login using OpenID", "$('login_container').toggle(); $('openid_container').toggle();" ) %br/ = f.text_field :login %p = f.label :password %br/ = f.password_field :password #openid_container{ display_none_if_openid_is_blank(@user_session) } = f.label :openid_identifier, "OpenID" (or = link_to_function "login using a standard username / password", "$('login_container').toggle(); $('openid_container').toggle();" ) %br/ = f.text_field :openid_identifier %p = f.check_box :remember_me = f.label :remember_me %p = f.submit "Login" END # Users file 'app/views/users/_form.html.haml', <<-END = form.label :login %br/ = form.text_field :login %br/ %br/ = form.label :password, form.object.new_record? ? nil : "Change password" %br/ = form.password_field :password %br/ %br/ = form.label :password_confirmation %br/ = form.password_field :password_confirmation %br/ %br/ = form.label :openid_identifier, "Or use OpenID instead of a standard login / password" %br/ = form.text_field :openid_identifier %br/ %br/ = form.label :email %br/ = form.text_field :email %br/ %br/ END file 'app/views/users/edit.html.haml', <<-END %h1 Edit My Account - form_for @user, :url => account_path do |f| = f.error_messages = render :partial => "form", :object => f = f.submit "Update" %br/ = link_to "My Profile", account_path END file 'app/views/users/new.html.haml', <<-END %h1 Register - form_for @user, :url => account_path do |f| = f.error_messages = render :partial => "form", :object => f = f.submit "Register" END file 'app/views/users/show.html.haml', <<-END - if @user.openid_identifier.blank? %p %strong Login: =h @user.login - else %p %strong OpenID: =h @user.openid_identifier %p %strong Email: =h @user.email %p %strong Login count: =h @user.login_count %p %strong Last request at: =h @user.last_request_at %p %strong Last login at: =h @user.last_login_at %p %strong Current login at: =h @user.current_login_at %p %strong Last login ip: =h @user.last_login_ip %p %strong Current login ip: =h @user.current_login_ip = link_to 'Edit', edit_account_path END # file 'app/models/notifier.rb', <<-END # class Notifier < ActionMailer::Base # default_url_options[:host] = "" # # def password_reset_instructions(user) # subject "Password Reset Instructions" # from "Binary Logic Notifier " # recipients user.email # sent_on Time.now # body :edit_password_reset_url => edit_password_reset_url(user.perishable_token) # end # end # END # Success! puts "" puts "" puts "**************************************" puts "*** ***" puts "*** Yippie, I just made something! ***" puts "*** ***" puts "**************************************" puts "" puts ""