adding error emails and invitation mailing
git-svn-id: http://svn.barleysodas.com/barleysodas/trunk@126 0f7b21a7-9e3a-4941-bbeb-ce5c7c368fa7master
parent
52c36c3891
commit
11e3356f55
|
@ -127,6 +127,23 @@ class ApplicationController < ActionController::Base
|
|||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Log the error and mail it out if the request is not a local request.
|
||||
# Usually only used in production mode.
|
||||
#
|
||||
def log_error(exception)
|
||||
super(exception)
|
||||
begin
|
||||
unless local_request? or RAILS_ENV == 'development' or
|
||||
exception.class == ActiveRecord::RecordNotFound
|
||||
ErrorMailer.deliver_snapshot(exception, clean_backtrace(exception),
|
||||
session.instance_variable_get("@data"), params, request.env)
|
||||
end
|
||||
rescue => e
|
||||
logger.info e.to_s
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
class InvitationsController < ApplicationController
|
||||
append_before_filter :ensure_xhr, :only => [ :create, :send ]
|
||||
|
||||
# GET /invitations
|
||||
# GET /invitations.xml
|
||||
def index
|
||||
@invitations = Invitation.find(:all, :include => [ 'people' ],
|
||||
:order => 'peoples.title ASC')
|
||||
respond_to do |format|
|
||||
format.html # index.rhtml
|
||||
format.xml { render :xml => @invitations.to_xml }
|
||||
end
|
||||
end
|
||||
|
||||
# POST /invitations
|
||||
def create
|
||||
@invitation = Invitation.new
|
||||
@invitation.people_id = params[:people_id].to_i if params[:people_id]
|
||||
@people = @invitation.people
|
||||
if @invitation.save
|
||||
render :partial => 'invitations/invitations'
|
||||
else
|
||||
render :inline => "<%= error_messages_for('invitation') -%>",
|
||||
:status => 500
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /invitations/1
|
||||
# DELETE /invitations/1.xml
|
||||
def destroy
|
||||
@invitation = Invitation.find(params[:id])
|
||||
@invitation.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to invitations_url }
|
||||
format.xml { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
def send_invitation
|
||||
@invitation = Invitation.find(:first, :include => [ 'people' ],
|
||||
:conditions => [ "people_id = ?", session[:people_id] ])
|
||||
@invitation ||= Invitation.new :people_id => session[:people_id]
|
||||
@people = @invitation.people
|
||||
recipient = params[:email].to_s
|
||||
begin
|
||||
if @invitation.new_record?
|
||||
@invitation.errors.add(:you, "have no invitations")
|
||||
end
|
||||
if recipient.to_s.empty?
|
||||
@invitation.errors.add(:recipient, "is missing")
|
||||
end
|
||||
raise "Misconfigured invitation!" unless @invitation.errors.empty?
|
||||
InvitationMailer.deliver_invitation(@invitation, recipient)
|
||||
rescue
|
||||
logger.info("Failed to deliver invitation: #{$!}")
|
||||
render :inline => "<%= error_messages_for('invitation') -%>",
|
||||
:status => 500
|
||||
return
|
||||
end
|
||||
@invitation.toggle! :sent
|
||||
render :partial => 'invitations/invitations'
|
||||
end
|
||||
end
|
|
@ -50,8 +50,10 @@ class PeoplesController < ApplicationController
|
|||
set_people_role
|
||||
@page = Page.new(params[:page])
|
||||
@people.page = @page
|
||||
invitation = Invitation.find_by_code(params[:code])
|
||||
respond_to do |format|
|
||||
if @people.save
|
||||
if invitation and @people.save
|
||||
invitation.destroy
|
||||
flash[:notice] = 'People was successfully created.'
|
||||
format.html { redirect_to people_url(@people.page.title_for_url) }
|
||||
format.xml { head :created,
|
||||
|
|
|
@ -116,7 +116,6 @@ module ApplicationHelper
|
|||
# Renders everything you need to display the TagImage browser.
|
||||
#
|
||||
def tagged_image_browser(obj)
|
||||
javascript_include_tag('control.modal.js') +
|
||||
render(:partial => 'shared/tagged_image_browser',
|
||||
:locals => { :obj => obj })
|
||||
end
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
module InvitationsHelper
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
class ErrorMailer < ActionMailer::Base
|
||||
def snapshot(exception, trace, session, params, env)
|
||||
@headers["Content-Type"] = "text/plain"
|
||||
@recipients = 'penguincoder@gmail.com'
|
||||
@from = 'BarleySodas <error@barleysodas.com>'
|
||||
@subject = "[BarleySodas Exception: #{env['REQUEST_URI']}]"
|
||||
@sent_on = Time.now
|
||||
@body["exception"] = exception
|
||||
@body["trace"] = trace
|
||||
@body["session"] = session
|
||||
@body["params"] = params
|
||||
@body["env"] = env
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
class Invitation < ActiveRecord::Base
|
||||
belongs_to :people
|
||||
validates_presence_of :people_id
|
||||
before_create :set_invitation_code
|
||||
|
||||
protected
|
||||
|
||||
def set_invitation_code
|
||||
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
||||
check = nil
|
||||
begin
|
||||
check = ''
|
||||
1.upto(32) { |k| check << chars[rand(chars.size - 1)] }
|
||||
end while Invitation.find_by_code(check)
|
||||
self.code = check
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class InvitationMailer < ActionMailer::Base
|
||||
def invitation(invitation, recipient)
|
||||
@headers["Content-Type"] = "text/plain"
|
||||
@recipients = recipient
|
||||
@from = 'BarleySodas <no-reply@barleysodas.com>'
|
||||
@subject = "You've been invited to BarleySodas!"
|
||||
@body["invitation"] = invitation
|
||||
@body["people_title"] = invitation.people.title
|
||||
end
|
||||
end
|
|
@ -14,6 +14,8 @@ class People < ActiveRecord::Base
|
|||
has_many :actual_friends, :through => :friends, :source => :destination
|
||||
has_many :experiences, :dependent => :destroy
|
||||
has_many :beers, :through => :experiences
|
||||
has_many :invitations, :dependent => :destroy,
|
||||
:conditions => [ 'sent IS NULL or sent = ?', false ]
|
||||
|
||||
make_authenticatable
|
||||
validates_length_of :password, :minimum => 8, :if => :password_required?,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
Error report from <%= Time.now %>
|
||||
|
||||
* Message: <%= @exception.message %>
|
||||
* Location: <%= @env['REQUEST_URI'] %>
|
||||
* Action: <%= @params.delete('action') %>
|
||||
* Controller: <%= @params.delete('controller') %>
|
||||
* Query: <%= @env['QUERY_STRING'] %>
|
||||
* Method: <%= @env['REQUEST_METHOD'] %>
|
||||
* SSL: <%= @env['SERVER_PORT'].to_i == 443 ? "true" : "false" %>
|
||||
* Agent: <%= @env['HTTP_USER_AGENT'] %>
|
||||
|
||||
Backtrace
|
||||
<%= @trace.to_a.join("\n") -%>
|
||||
|
||||
<% if @params -%>
|
||||
Params
|
||||
<% for key, val in @params -%>
|
||||
* <%= key %>
|
||||
<%= val.to_yaml.to_a.join("\n ") %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
||||
<% if @session -%>
|
||||
Session
|
||||
<% for key, val in @session -%>
|
||||
<% next if key.to_s == 'permissions' -%>
|
||||
* <%= key %>
|
||||
<%= val.to_yaml.to_a.join("\n ") %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
||||
<% if @env -%>
|
||||
Environment
|
||||
<% for key, val in @env -%>
|
||||
* <%= key %>
|
||||
<%= val.to_yaml.to_a.join("\n ") %>
|
||||
<% end -%>
|
||||
<% end -%>
|
|
@ -0,0 +1,13 @@
|
|||
Hello!
|
||||
|
||||
You have been nice enough that someone has given you an invitation to join
|
||||
the best beer site. We have a wiki, style guidelines, beers, breweries,
|
||||
and sweet image tagging that lets you build a network of things and places
|
||||
experienced in your journey through inebriation.
|
||||
|
||||
Sign up today at:
|
||||
<%= new_people_url(:code => @invitation.code, :host => "barleysodas.com") %>
|
||||
|
||||
Thanks,
|
||||
|
||||
The BarleySodas Society for the preservation of ancient and modern techniques regarding both the intellectual and philisophical management of varied sizes animals vice the expected volume of celestial entities older than, but not equal to, sixteen billion years in age.
|
|
@ -0,0 +1,2 @@
|
|||
You have <strong><%= pluralize(@people.invitations.size, 'Invitations') rescue '0 Invitations' -%></strong>.
|
||||
<% if @people and !@people.invitations.empty? -%><br /><%= link_to_function 'Send Invitation', "lightboxes['invitation_dialog'].open()" -%><% end -%>
|
|
@ -0,0 +1,12 @@
|
|||
<h1>Editing invitation</h1>
|
||||
|
||||
<%= error_messages_for :invitation %>
|
||||
|
||||
<% form_for(:invitation, :url => invitation_path(@invitation), :html => { :method => :put }) do |f| %>
|
||||
<p>
|
||||
<%= submit_tag "Update" %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Show', invitation_path(@invitation) %> |
|
||||
<%= link_to 'Back', invitations_path %>
|
|
@ -0,0 +1,18 @@
|
|||
<h1>Listing invitations</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
</tr>
|
||||
|
||||
<% for invitation in @invitations %>
|
||||
<tr>
|
||||
<td><%= link_to 'Show', invitation_path(invitation) %></td>
|
||||
<td><%= link_to 'Edit', edit_invitation_path(invitation) %></td>
|
||||
<td><%= link_to 'Destroy', invitation_path(invitation), :confirm => 'Are you sure?', :method => :delete %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
<%= link_to 'New invitation', new_invitation_path %>
|
|
@ -0,0 +1,11 @@
|
|||
<h1>New invitation</h1>
|
||||
|
||||
<%= error_messages_for :invitation %>
|
||||
|
||||
<% form_for(:invitation, :url => invitations_path) do |f| %>
|
||||
<p>
|
||||
<%= submit_tag "Create" %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', invitations_path %>
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
<%= link_to 'Edit', edit_invitation_path(@invitation) %> |
|
||||
<%= link_to 'Back', invitations_path %>
|
|
@ -5,6 +5,8 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<%= stylesheet_link_tag 'application', :media => 'all' %>
|
||||
<%= javascript_include_tag :defaults %>
|
||||
<%= javascript_include_tag 'control.modal.js' %>
|
||||
<%= javascript_include_tag 'control.rating.js' %>
|
||||
<script type="text/javascript">
|
||||
<%= yield :script %>
|
||||
</script>
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
<label for="people_title">Name</label> <%= text_field 'people', 'title' %>
|
||||
</p>
|
||||
<p>
|
||||
<label for="people_password">Password</label> <%= text_field 'people', 'password' %>
|
||||
<label for="people_password">Password</label> <%= password_field 'people', 'password' %>
|
||||
</p>
|
||||
<p>
|
||||
<label for="people_password_confirmation">Password Confirmation</label> <%= text_field 'people', 'password_confirmation' %>
|
||||
<label for="people_password_confirmation">Password Confirmation</label> <%= password_field 'people', 'password_confirmation' %>
|
||||
</p>
|
||||
<%= render :partial => 'pages/page_form' %>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<%= error_messages_for :people %>
|
||||
|
||||
<% form_for(:people, :url => peoples_path) do |f| %>
|
||||
<% form_for(:people, :url => peoples_path, :code => params[:code]) do |f| %>
|
||||
<p>Invitation Code: <strong><%= params[:code] -%></strong><%= hidden_field_tag 'code', params[:code] -%></p>
|
||||
<%= render :partial => 'people_form' %>
|
||||
<p>
|
||||
<%= submit_tag "Create" %>
|
||||
|
|
|
@ -2,6 +2,16 @@
|
|||
|
||||
<%= render :partial => 'pages/page' %>
|
||||
|
||||
<% lightbox :title => 'Send An Invitation', :window_id => 'invitation_dialog' do -%>
|
||||
<div id="invitation_errors"></div>
|
||||
<div class="centered">
|
||||
<p>Enter the recipient's email address: <%= text_field_tag 'email' -%></p>
|
||||
</div>
|
||||
<div class="dialogControls">
|
||||
<%= link_to_remote "Send", :url => { :controller => :invitations, :action => :send_invitation }, :with => "'email='+escape($('email').value)", :update => { :failure => 'invitation_errors', :success => 'person_invitations' }, :success => "Control.Modal.close()" -%>
|
||||
</div>
|
||||
<% end -%>
|
||||
|
||||
<% content_for :sidebar do -%>
|
||||
<%= new_people_link -%><br />
|
||||
<%= edit_people_link(@people) %><br />
|
||||
|
@ -11,4 +21,6 @@
|
|||
<% unless @people.id == session[:people_id] or @people.friend_of?(session[:people_id]) -%><%= add_friend_link(@people) -%><% end -%>
|
||||
<% if @people.friend_of?(session[:people_id]) -%><%= remove_friend_link(@people) -%><br /><% end -%>
|
||||
<%= link_to "#{pluralize(@people.beers.size, 'Beer')} Experience", experience_path(:id => @people.page.title_for_url) -%><br />
|
||||
<span id="person_invitations"><%= render :partial => 'invitations/invitations' -%></span><br />
|
||||
<% if has_permission_for_action?(:create, :invitations) -%><%= link_to_remote "#{image_tag('list-add.png')} Invitation", :update => 'person_invitations', :url => invitations_path, :with => "'people_id=#{@people.id}'", :success => "new Effect.Highlight('person_invitations', { duration: 2.0 })" -%><br /><% end -%>
|
||||
<% end -%>
|
|
@ -2,9 +2,12 @@ RAILS_GEM_VERSION = '1.2.3' unless defined? RAILS_GEM_VERSION
|
|||
require File.join(File.dirname(__FILE__), 'boot')
|
||||
|
||||
Rails::Initializer.run do |config|
|
||||
config.frameworks -= [ :action_web_service, :action_mailer ]
|
||||
config.frameworks -= [ :action_web_service ]
|
||||
config.action_controller.session_store = :active_record_store
|
||||
config.active_record.default_timezone = :utc
|
||||
config.action_mailer.delivery_method = :sendmail
|
||||
config.action_mailer.perform_deliveries = true
|
||||
config.action_mailer.raise_delivery_errors = true
|
||||
end
|
||||
|
||||
require 'redcloth'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
ActionController::Routing::Routes.draw do |map|
|
||||
map.resources :beers, :breweries, :pages, :discussions, :peoples, :roles,
|
||||
:sessions, :styles, :galleries, :tag_images, :friends, :experiences
|
||||
:sessions, :styles, :galleries, :tag_images, :friends, :experiences,
|
||||
:invitations
|
||||
map.connect ':controller/:action/:id.:format'
|
||||
map.connect ':controller/:action/:id'
|
||||
map.connect '/', :controller => 'pages', :action => 'default_action'
|
||||
|
|
|
@ -10,6 +10,8 @@ class CreateRoles < ActiveRecord::Migration
|
|||
br = Role.create :code => 'base', :name => 'Base Role'
|
||||
ar = Role.create :code => 'admin', :name => 'Administrative Role',
|
||||
:parent_id => br.id
|
||||
nr = Role.create :code => 'normal', :name => 'Normal User Role',
|
||||
:parent_id => br.id
|
||||
end
|
||||
|
||||
def self.down
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
class CreateInvitations < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :invitations do |t|
|
||||
t.column :code, :string, :limit => 32
|
||||
t.column :people_id, :integer
|
||||
t.column :sent, :boolean, :default => false
|
||||
end
|
||||
add_index :invitations, :people_id
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :invitations
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ base_actions = ApplicationController.action_methods
|
|||
controllers = [ PagesController, DiscussionsController, StylesController,
|
||||
PeoplesController, BeersController, BreweriesController, RolesController,
|
||||
GalleriesController, TagImagesController, FriendsController,
|
||||
ExperiencesController ]
|
||||
ExperiencesController, InvitationsController ]
|
||||
controllers.each do |c|
|
||||
actions = c.action_methods - base_actions
|
||||
cname = c.controller_name
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||
one:
|
||||
id: 1
|
||||
two:
|
||||
id: 2
|
|
@ -0,0 +1,57 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'invitations_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class InvitationsController; def rescue_action(e) raise e end; end
|
||||
|
||||
class InvitationsControllerTest < Test::Unit::TestCase
|
||||
fixtures :invitations
|
||||
|
||||
def setup
|
||||
@controller = InvitationsController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
def test_should_get_index
|
||||
get :index
|
||||
assert_response :success
|
||||
assert assigns(:invitations)
|
||||
end
|
||||
|
||||
def test_should_get_new
|
||||
get :new
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_should_create_invitation
|
||||
old_count = Invitation.count
|
||||
post :create, :invitation => { }
|
||||
assert_equal old_count+1, Invitation.count
|
||||
|
||||
assert_redirected_to invitation_path(assigns(:invitation))
|
||||
end
|
||||
|
||||
def test_should_show_invitation
|
||||
get :show, :id => 1
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_should_get_edit
|
||||
get :edit, :id => 1
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_should_update_invitation
|
||||
put :update, :id => 1, :invitation => { }
|
||||
assert_redirected_to invitation_path(assigns(:invitation))
|
||||
end
|
||||
|
||||
def test_should_destroy_invitation
|
||||
old_count = Invitation.count
|
||||
delete :destroy, :id => 1
|
||||
assert_equal old_count-1, Invitation.count
|
||||
|
||||
assert_redirected_to invitations_path
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class InvitationTest < Test::Unit::TestCase
|
||||
fixtures :invitations
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
Reference in New Issue