malkomalko
2/22/2009 - 1:37 PM

gistfile1.rb

# 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 <noreply@binarylogic.com>"
  #         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 ""