fundraiser 1.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +72 -0
  3. data/Rakefile +35 -0
  4. data/app/assets/javascripts/fundraiser/application.js +15 -0
  5. data/app/assets/stylesheets/fundraiser/application.css +13 -0
  6. data/app/assets/stylesheets/fundraiser/styles/forms.css.scss +16 -0
  7. data/app/controllers/fundraiser/application_controller.rb +14 -0
  8. data/app/controllers/fundraiser/home_controller.rb +4 -0
  9. data/app/controllers/fundraiser/ipns_controller.rb +24 -0
  10. data/app/controllers/fundraiser/manage/base_controller.rb +7 -0
  11. data/app/controllers/fundraiser/manage/rewards_controller.rb +45 -0
  12. data/app/controllers/fundraiser/manage/settings_controller.rb +17 -0
  13. data/app/controllers/fundraiser/pledges_controller.rb +32 -0
  14. data/app/controllers/fundraiser/rewards_controller.rb +9 -0
  15. data/app/controllers/fundraiser/thanks_controller.rb +6 -0
  16. data/app/helpers/fundraiser/application_helper.rb +16 -0
  17. data/app/models/fundraiser/contribution.rb +25 -0
  18. data/app/models/fundraiser/pledge.rb +8 -0
  19. data/app/models/fundraiser/reward.rb +10 -0
  20. data/app/models/fundraiser/settings.rb +39 -0
  21. data/app/views/fundraiser/application/_alerts.html.haml +5 -0
  22. data/app/views/fundraiser/application/_bootstrap_text_area.html.haml +9 -0
  23. data/app/views/fundraiser/application/_bootstrap_text_field.html.haml +9 -0
  24. data/app/views/fundraiser/application/_navbar.html.haml +6 -0
  25. data/app/views/fundraiser/devise/sessions/new.html.haml +16 -0
  26. data/app/views/fundraiser/home/show.html.haml +1 -0
  27. data/app/views/fundraiser/manage/rewards/_form.html.haml +3 -0
  28. data/app/views/fundraiser/manage/rewards/_reward.html.haml +6 -0
  29. data/app/views/fundraiser/manage/rewards/edit.html.haml +10 -0
  30. data/app/views/fundraiser/manage/rewards/index.html.haml +6 -0
  31. data/app/views/fundraiser/manage/rewards/new.html.haml +10 -0
  32. data/app/views/fundraiser/manage/settings/edit.html.haml +15 -0
  33. data/app/views/fundraiser/pledges/new.html.haml +19 -0
  34. data/app/views/fundraiser/pledges/show.html.haml +1 -0
  35. data/app/views/fundraiser/rewards/_reward.html.haml +5 -0
  36. data/app/views/fundraiser/rewards/index.html.haml +7 -0
  37. data/app/views/fundraiser/thanks/show.html.haml +1 -0
  38. data/app/views/layouts/fundraiser/application.html.haml +13 -0
  39. data/config/initializers/settings.rb +6 -0
  40. data/config/locales/devise.en.yml +58 -0
  41. data/config/routes.rb +13 -0
  42. data/db/migrate/20121008183146_create_fundraiser_settings.rb +10 -0
  43. data/db/migrate/20121009000016_create_fundraiser_rewards.rb +11 -0
  44. data/db/migrate/20121009070136_create_fundraiser_pledges.rb +19 -0
  45. data/db/migrate/20121010182436_create_fundraiser_contributions.rb +12 -0
  46. data/lib/amazon/fps/signature_utils.rb +142 -0
  47. data/lib/amazon/fps/signature_utils_for_outbound.rb +179 -0
  48. data/lib/amazon/fps/widget.rb +58 -0
  49. data/lib/fundraiser.rb +16 -0
  50. data/lib/fundraiser/engine.rb +5 -0
  51. data/lib/fundraiser/version.rb +3 -0
  52. data/lib/generators/fundraiser/views_generator.rb +11 -0
  53. data/lib/tasks/fundraiser_tasks.rake +7 -0
  54. metadata +293 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Crowd Interactive
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,72 @@
1
+ # Fundraiser
2
+
3
+ [![Build Status](https://secure.travis-ci.org/crowdint/fundraiser.png)](http://travis-ci.org/crowdint/fundraiser)
4
+
5
+ Mountable Engine to set up a Crowdfunding app. Uses Amazon Simplepay to collect
6
+ payments.
7
+
8
+ Please, refer to the wiki for guidance on how to get an Amazon AWS account.
9
+
10
+ ## Requirements
11
+
12
+ * Rails 3.2+
13
+
14
+ ## Installation
15
+
16
+ Gemfile
17
+
18
+ gem 'fundraiser'
19
+
20
+ Bundle
21
+
22
+ bundle
23
+
24
+ Copy migrations from Fundraiser
25
+
26
+ rake fundraiser:install:migrations
27
+
28
+ Run them
29
+
30
+ rake db:migrate
31
+
32
+ Mount the engine on routes.rb
33
+
34
+ Rails.application.routes.draw do
35
+ mount Fundraiser::Engine => "/fundraiser"
36
+ end
37
+
38
+ ## Authentication
39
+
40
+ ### Devise
41
+
42
+ To authenticate using devise, simply install it and create a User model. It
43
+ should run out of the box.
44
+
45
+ Gemfile:
46
+
47
+ gem 'devise'
48
+
49
+ Run:
50
+
51
+ rails generator devise user
52
+
53
+ rake db:migrate
54
+
55
+ ## Manage
56
+
57
+ Use the console to create your first user and browse to /manage
58
+
59
+ Log in and enjoy.
60
+
61
+ # About the author
62
+
63
+ [Crowd Interactive](http://www.crowdint.com) is a leading Ruby and Rails
64
+ consultancy firm based in Mexico currently doing business with startups
65
+ in the United States. We specialize in building and growing your existing
66
+ development team, by adding engineers onsite or offsite. We pick our clients
67
+ carefully, as we only work with companies we believe in. Find out more about
68
+ us on our [website](http://www.crowdint.com).
69
+
70
+ # Licencse
71
+
72
+ MIT License. Copyright 2012 Crowd Interactive.
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Fundraiser'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("./dummy/Rakefile")
24
+ load 'rails/tasks/engine.rake'
25
+
26
+ require 'rspec/core/rake_task'
27
+
28
+ task 'db:test:prepare' => 'app:db:test:prepare'
29
+
30
+ RSpec::Core::RakeTask.new :default
31
+
32
+
33
+
34
+ Bundler::GemHelper.install_tasks
35
+
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,16 @@
1
+ $error_color: #B94A48;
2
+
3
+ .field_with_errors {
4
+ color: $error_color;
5
+
6
+ input {
7
+ border-color: $error_color;
8
+ color: $error_color;
9
+ }
10
+ }
11
+
12
+ .help-inline.error {
13
+ color: $error_color;
14
+ font-size: 10px;
15
+ text-align: right;
16
+ }
@@ -0,0 +1,14 @@
1
+ module Fundraiser
2
+ class ApplicationController < ActionController::Base
3
+ def method_missing(method_name)
4
+ if method_name == :authenticate_user!
5
+ Rails.logger.warn("authenticate_user! in Crowdblog::ApplicationController should be overriden")
6
+ end
7
+ end
8
+
9
+ protected
10
+ def sanity_check
11
+ redirect_to fundraiser.edit_manage_settings_path unless Fundraiser::Settings.try(:funding_goal)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ class Fundraiser::HomeController < Fundraiser::ApplicationController
2
+ def show
3
+ end
4
+ end
@@ -0,0 +1,24 @@
1
+ module Fundraiser
2
+ class IpnsController < ApplicationController
3
+ def create
4
+ aws_access_key = ENV['FPS_AWS_ACCESS_KEY_ID']
5
+ aws_secret_key = ENV['FPS_AWS_SECRET_ACCESS_KEY']
6
+
7
+ utils = Amazon::FPS::SignatureUtilsForOutbound.new(aws_access_key, aws_secret_key)
8
+
9
+ params.delete :controller
10
+ params.delete :action
11
+
12
+ if utils.validate_request(:parameters => params, :url_end_point => url_end_point, :http_method => "POST")
13
+ Contribution.create_from_amazon_ipn params
14
+ render :text => "OK"
15
+ else
16
+ render :text => "NOT OK"
17
+ end
18
+ end
19
+
20
+ def url_end_point
21
+ fundraiser.ipns_url
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ class Fundraiser::Manage::BaseController < Fundraiser::ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def after_sign_in_path_for(resource)
5
+ fundraiser.root_path
6
+ end
7
+ end
@@ -0,0 +1,45 @@
1
+ class Fundraiser::Manage::RewardsController < Fundraiser::Manage::BaseController
2
+ before_filter :load_reward, :only => [ :edit, :update, :destroy ]
3
+
4
+ def index
5
+ @rewards = Fundraiser::Reward.all
6
+ end
7
+
8
+ def new
9
+ @reward = Fundraiser::Reward.new
10
+ end
11
+
12
+ def create
13
+ @reward = Fundraiser::Reward.new(reward_params)
14
+ if @reward.save
15
+ redirect_to manage_rewards_path, :notice => "Reward was succesfully created"
16
+ else
17
+ render :action => :new
18
+ end
19
+ end
20
+
21
+ def edit
22
+ end
23
+
24
+ def update
25
+ if @reward.update_attributes(reward_params)
26
+ redirect_to fundraiser.manage_rewards_path, :notice => "Reward was succesfully updated"
27
+ else
28
+ render :action => :edit
29
+ end
30
+ end
31
+
32
+ def destroy
33
+ @reward.destroy
34
+ redirect_to manage_rewards_path, :notice => "Reward was succesfully deleted"
35
+ end
36
+
37
+ private
38
+ def reward_params
39
+ params[:reward]
40
+ end
41
+
42
+ def load_reward
43
+ @reward = Fundraiser::Reward.find(params[:id])
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ module Fundraiser
2
+ class Manage::SettingsController < Fundraiser::Manage::BaseController
3
+ def edit
4
+ @settings = Settings.new
5
+ end
6
+
7
+ def update
8
+ Fundraiser::Settings.store settings_params
9
+ redirect_to fundraiser.edit_manage_settings_path, :notice => 'Settings updated succesfully'
10
+ end
11
+
12
+ private
13
+ def settings_params
14
+ params[:settings]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ module Fundraiser
2
+ class PledgesController < ApplicationController
3
+ before_filter :authenticate_user!, :load_reward
4
+
5
+ def new
6
+ @pledge = Pledge.new(:pledge_amount => params[:pledge_amount])
7
+ end
8
+
9
+ def create
10
+ @pledge = @reward.pledges.build(pledge_params)
11
+ @pledge.user = current_user
12
+ if @pledge.save
13
+ redirect_to fundraiser.reward_pledge_path(@reward, @pledge)
14
+ else
15
+ render :action => :new
16
+ end
17
+ end
18
+
19
+ def show
20
+ @pledge = Pledge.find(params[:id])
21
+ end
22
+
23
+ private
24
+ def load_reward
25
+ @reward = Reward.find(params[:reward_id])
26
+ end
27
+
28
+ def pledge_params
29
+ params[:pledge]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ module Fundraiser
2
+ class RewardsController < ApplicationController
3
+ before_filter :sanity_check
4
+
5
+ def index
6
+ @rewards = Reward.all
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Fundraiser
2
+ class ThanksController < ApplicationController
3
+ def show
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ module Fundraiser
2
+ module ApplicationHelper
3
+ def bootstrap_text_field(f, column, input_class = "")
4
+ render "bootstrap_text_field", :f => f, :column => column, :input_class => input_class
5
+ end
6
+
7
+ def bootstrap_text_area(f, column, input_class = "")
8
+ render "bootstrap_text_area", :f => f, :column => column, :input_class => input_class
9
+ end
10
+
11
+ def simplepay_button(reward)
12
+ amount = "USD #{reward.minimum_pledge}"
13
+ Amazon::FPS::Widget.widget amount, reward.title, reward.id, fundraiser.rewards_url, fundraiser.ipns_url
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Fundraiser
2
+ class Contribution < ActiveRecord::Base
3
+ attr_accessible :amount, :email, :reference, :transaction
4
+
5
+ serialize :request_params
6
+
7
+ def self.create_from_amazon_ipn(params)
8
+ create(
9
+ :email => params["buyerEmail"],
10
+ :reference => params["referenceId"],
11
+ :request_params => params,
12
+ :amount => amazon_amount_to_cents(params["transactionAmount"])
13
+ )
14
+ end
15
+
16
+ def self.amazon_amount_to_cents(amount_with_currency)
17
+ amount = amount_with_currency.split(' ').last
18
+ (amount.to_f * 100).to_i
19
+ end
20
+
21
+ def self.total_contributed
22
+ sum(:amount) / 100
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ module Fundraiser
2
+ class Pledge < ActiveRecord::Base
3
+ attr_accessible :address_line_1, :address_line_2, :city, :country,
4
+ :phone, :pledge_amount, :state, :user_id, :zip_code, :name
5
+
6
+ belongs_to :user
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Fundraiser
2
+ class Reward < ActiveRecord::Base
3
+ attr_accessible :description, :minimum_pledge, :title
4
+
5
+ validates :title, :presence => true
6
+ validates :minimum_pledge, :numericality => true
7
+
8
+ has_many :pledges
9
+ end
10
+ end
@@ -0,0 +1,39 @@
1
+ module Fundraiser
2
+ class Settings < ActiveRecord::Base
3
+ include Persistent::Settings
4
+
5
+ AMAZON_SETTINGS = [ :aws_access_key, :aws_secret_key ]
6
+ GENERAL_SETTINGS = [ :funding_goal, :funding_end_date ]
7
+
8
+ attr_accessible :var, :value
9
+
10
+ (AMAZON_SETTINGS + GENERAL_SETTINGS).each do |column|
11
+ attr_accessor column
12
+ define_method column do
13
+ Fundraiser::Settings.send(column)
14
+ end
15
+ end
16
+
17
+ def self.store(hash)
18
+ hash.each do |key, value|
19
+ send("#{key}=", value)
20
+ end
21
+ end
22
+
23
+ def self.ready?
24
+ table_exists?
25
+ end
26
+
27
+ def self.amazon!
28
+ Fundraiser::Settings::AMAZON_SETTINGS.each do |setting|
29
+ begin
30
+ Fundraiser::Settings.send setting
31
+ rescue
32
+ Fundraiser::Settings.send "#{setting}=", ""
33
+ end
34
+ end
35
+ end
36
+
37
+ load_from_persistance
38
+ end
39
+ end