Skip to content

Instantly share code, notes, and snippets.

@mattpolito
Forked from peterc/gist:33337
Created January 26, 2009 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mattpolito/52982 to your computer and use it in GitHub Desktop.
Save mattpolito/52982 to your computer and use it in GitHub Desktop.
# 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 ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment