implement plan code

This commit is contained in:
Kyle Drake 2014-04-18 15:40:08 -07:00
parent 138725d00b
commit 1031324920
No known key found for this signature in database
GPG key ID: 8BE721072E1864BE
17 changed files with 266 additions and 114 deletions

View file

@ -18,6 +18,7 @@ gem 'mail'
gem 'google-api-client', require: 'google/api_client'
gem 'tilt'
gem 'erubis'
gem 'stripe', :git => 'https://github.com/stripe/stripe-ruby'
platform :mri do
gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic

View file

@ -1,3 +1,12 @@
GIT
remote: https://github.com/stripe/stripe-ruby
revision: 48f76057f425ab5c3bb147f3d71c3d36d951159f
specs:
stripe (1.11.0)
json (~> 1.8.1)
mime-types (~> 1.25)
rest-client (~> 1.4)
GEM
remote: https://rubygems.org/
specs:
@ -121,11 +130,12 @@ GEM
redis (3.0.7)
redis-namespace (1.4.1)
redis (~> 3.0.4)
rest-client (1.6.7)
mime-types (>= 1.16)
retriable (1.4.1)
rmagick (2.13.2)
rubyzip (1.1.2)
safe_yaml (1.0.1)
sass (3.3.5)
selenium-webdriver (2.40.0)
childprocess (>= 0.5.0)
multi_json (~> 1.0)
@ -230,5 +240,6 @@ DEPENDENCIES
sinatra-flash
sinatra-xsendfile
slim
stripe!
tilt
webmock

52
app.rb
View file

@ -74,6 +74,12 @@ get '/?' do
erb :index, layout: false
end
get '/site/:username/tip' do |username|
@site = Site[username: username]
@title = "Tip #{@site.title}"
erb :'tip'
end
get '/browse' do
@current_page = params[:current_page]
@current_page = @current_page.to_i
@ -128,22 +134,7 @@ get '/new' do
dashboard_if_signed_in
@site = Site.new
@site.username = params[:username] unless params[:username].nil?
slim :'new'
end
get '/dashboard' do
require_login
erb :'dashboard'
end
get '/signin' do
dashboard_if_signed_in
slim :'signin'
end
get '/settings' do
require_login
slim :'settings'
erb :'new'
end
post '/create' do
@ -160,17 +151,44 @@ post '/create' do
recaptcha_is_valid = ENV['RACK_ENV'] == 'test' || recaptcha_valid?
if @site.valid? && recaptcha_is_valid
DB.transaction do
if !params[:stripe_token].nil? && params[:stripe_token] != ''
customer = Stripe::Customer.create(
card: params[:stripe_token],
description: @site.username,
email: @site.email,
plan: params[:selected_plan]
)
@site.stripe_customer_id = customer.id
end
@site.save
end
session[:id] = @site.id
redirect '/dashboard'
else
@site.errors.add :captcha, 'You must type in the two words correctly! Try again.' if !recaptcha_is_valid
slim :'/new'
erb :'/new'
end
end
get '/dashboard' do
require_login
erb :'dashboard'
end
get '/signin' do
dashboard_if_signed_in
slim :'signin'
end
get '/settings' do
require_login
slim :'settings'
end
post '/signin' do
dashboard_if_signed_in

View file

@ -8,3 +8,17 @@ development:
sidekiq_pass: ENTER PASS HERE
phantomjs_url:
- http://localhost:8910
stripe_publishable_key: fillout
stripe_api_key: fillout
test:
database: 'postgres://neocities@127.0.0.1/neocities_test'
database_pool: 1
session_secret: SECRET GOES HERE
recaptcha_public_key: ENTER PUBLIC KEY HERE
recaptcha_private_key: ENTER PRIVATE KEY HERE
sidekiq_user: ENTER USER HERE
sidekiq_pass: ENTER PASS HERE
phantomjs_url:
- http://localhost:8910
stripe_publishable_key: fillout
stripe_api_key: fillout

View file

@ -58,6 +58,8 @@ Sequel::Model.plugin :defaults_setter
Sequel.default_timezone = 'UTC'
Sequel::Migrator.apply DB, './migrations'
Stripe.api_key = $config['stripe_api_key']
Dir.glob('models/*.rb').each {|m| require File.join(DIR_ROOT, "#{m}") }
DB.loggers << Logger.new(STDOUT) if ENV['RACK_ENV'] == 'development'

View file

@ -0,0 +1,11 @@
Sequel.migration do
up {
DB.drop_column :sites, :stripe_token
DB.add_column :sites, :stripe_customer_id, :text, default: nil
}
down {
DB.drop_column :sites, :stripe_customer_id
DB.add_column :sites, :stripe_token, :text, default: nil
}
end

View file

@ -311,4 +311,8 @@ class Site < Sequel::Model
def available_space_in_megabytes
(available_space.to_f / 2**20).round(2)
end
def title
values[:title] || values[:username]
end
end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

File diff suppressed because one or more lines are too long

View file

@ -20,7 +20,6 @@
</div>
<% end %>
<h2>Contact Us</h2>
<h6>Please Note Before Contacting:</h6>

View file

@ -322,21 +322,8 @@
<%== erb :'_footer', layout: false%>
</footer>
</div> <!-- end .page -->
<!-- scripts -->
<script src="assets/scripts/jquery-1.10.1.min.js"></script>
<script src="assets/scripts/app.min.js"></script> <!-- Script block allowing child pages to inject their own scripts -->
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID.
<script type="text/javascript>
var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src='//www.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
-->
</div>
<script src="/assets/scripts/jquery-1.11.0.min.js"></script>
<script src="/assets/scripts/app.min.js"></script>
</body>
</html>

View file

@ -20,7 +20,7 @@
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="assets/css/neo.min.css" rel="stylesheet" type="text/css" media="all"/>
<link href="/assets/css/neo.min.css" rel="stylesheet" type="text/css" media="all"/>
<link href="/css/font-awesome.min.css" rel="stylesheet" type="text/css" media="all"/>
<link href="/css/styles.css" rel="stylesheet" type="text/css" media="all">
@ -35,6 +35,10 @@
<!--[if lt IE 9]>
<script type="text/javascript" src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script>
var RecaptchaOptions = {theme: 'clean'}
</script>
</head>
<body class="interior">
@ -46,8 +50,8 @@
<%== erb :'_footer', layout: false %>
</footer>
<script src="assets/scripts/jquery-1.10.1.min.js"></script>
<script src="assets/scripts/nav.min.js"></script>
<script src="/assets/scripts/jquery-1.11.0.min.js"></script>
<script src="/assets/scripts/nav.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>

View file

@ -12,7 +12,7 @@ html
meta property="og:title" content="NeoCities"
meta property="og:description" content="NeoCities is the new Geocities. Create your own free home page, and do whatever you want with it."
meta name="csrf-token" content="#{csrf_token}"
script src="/js/jquery.min.js"
script src="/assets/scripts/jquery-1.11.0.min.js"
link href="/assets/css/neo.min.css" rel="stylesheet" type="text/css" media="all"
script src="/assets/scripts/nav.min.js"

170
views/new.erb Normal file
View file

@ -0,0 +1,170 @@
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript">
Stripe.setPublishableKey('<%= $config['stripe_publishable_key'] %>');
</script>
<main class="content-Base">
<div class="row content">
<div class="col col-100">
<form method="POST" action="/create" id="signupform">
<input name="csrf_token" type="hidden" value="<%= csrf_token %>">
<h2 class="txt-Center">Create a New Home Page</h2>
<div class="col col-50" style="margin:0 auto; float:none">
<% if !@site.errors.empty? %>
<div class="row content">
<div class="col col-100 txt-Center">
<div class="alert alert-block alert-error">
<p>There were errors creating your home page:</p>
<% @site.errors.each do |error| %>
<p class="tiny"><%= error.last.first %></p>
<% end %>
</div>
</div>
</div>
<% end %>
<hr>
<p class="tiny">
First, enter a username. This will also be used as your site name.<br><b>Do not forget this, it will be used to sign in to and manage your home page.</b> It can only contain letters, numbers, underscores and hyphens, and can only be 32 characters long.
</p>
<h5>Username</h5>
<p class="tiny">
<input class="input-Area" name="username" type="text" placeholder="yourusername" value="<%= @site.username %>" autocapitalize="off" autocorrect="off">.neocities.org
</p>
<hr>
<p class="tiny">
Next, enter a password. This will be used to allow you to login. Minimum 5 characters. If you don't make it a good password, Dade Murphy from the movie Hackers will come in and steal your "garbage files".
</p>
<h5>Password</h5>
<input class="input-Area" name="password" type="password">
<hr>
<p class="tiny">
Now you can enter an e-mail address. Your e-mail address is private and we will not show it to anyone for any reason. You don't have to provide one, but <b>we will not be able to reset your password without it, so don't lose your username and password if you leave this blank!</b>
</p>
<h5>Email</h5>
<input class="input-Area" name="email" type="email" placeholder="youremail@example.com" value="<%= @site.email %>">
<hr>
<p class="tiny">You can optionally enter some tags! Tags will allow others to find your site based on your interests, or your site's theme. <b>Separate multiple tags with commas</b>. Don't think too hard about this, you can change them later. You can have a maximum of ten tags, and there is a two word per tag maximum (extra words in a tag will be removed).</p>
<h5>Tags</h5>
<input class="input-Area" name="tags" type="text" style="width: 400px; max-width:100%" placeholder="pokemon, video games, bulbasaur" value="<%= params[:tags] %>" autocapitalize="off" autocorrect="off">
<hr>
<p class="tiny"><strong>The site you are creating will be free, forever.</strong> We will never charge you for your free web site.</p>
<p class="tiny"><a href="/donate" target="_blank">Neocities has to pay the bills though</a>, and we like the idea of being able to work on the site full-time someday. So if you would like to help us reach this goal, we have created the <strong>Supporter Plan</strong>!
<p class="tiny">Right now, the <strong>Supporter Plan</strong> is the same as the free plan, except that <strong>Supporter Plan members get 200MB</strong> of web space. You will also be listed as a supporter on our contributors page, and on your site profile page.</p>
<p class="tiny">The base plan is $12 per year ($1/mo) paid annually, which is the cost of <a href="/img/yafagrillmenu.jpg" target="_blank">a delicious Yafa Combo with a lousy tip</a>. If you ever decide to cancel, you get to keep the extra space.</p>
<div>
<input type="radio" name="plan" value="free" <%= params[:plan].nil? || params[:plan] == 'free' ? 'checked' : '' %>>
<span><strong>Free Plan (10MB)</strong></span>
</div>
<a name="plan_error_link"></a>
<div>
<input id="supporter" type="radio" name="plan" value="supporter" <%= params[:plan] == 'supporter' ? 'checked' : '' %>>
<span><strong>Supporter Plan (200MB)</strong></span>
</div>
<div id="plan_container" style="margin-top:20px; display: none">
<input id="stripe_token" name="stripe_token" type="hidden" value="<%= params[:stripe_token] %>">
<div id="plan_error" class="alert alert-block alert-error" style="display:none"></div>
<p class="tiny">
Plan type:
<select name="selected_plan" style="width: 200px">
<option value="plan_one">$12/year ($1/month)</option>
<option value="plan_two" <%= params[:selected_plan].nil? ? 'selected' : '' %>>$24/year ($2/month)</option>
<option value="plan_three">$36/year ($3/month)</option>
<option value="plan_four">$48/year ($4/month)</option>
<option value="plan_five">$60/year ($5/month)</option>
</select>
</p>
<% if params[:stripe_token] %>
<p class="tiny">Billing information has been saved, thank you!</p>
<% else %>
<p class="tiny">
Card Number: <input type="text" size="20" data-stripe="number">
CVC: <input type="text" size="4" maxlength="4" data-stripe="cvc" style="width: 60px">
</p>
<p class="tiny">
Expiration:
<input type="text" size="2" data-stripe="exp-month" placeholder="MM" maxlength="2" style="width: 50px">
<input type="text" size="4" data-stripe="exp-year" placeholder="YYYY" maxlength="4" style="width: 60px">
</p>
<% end %>
</div>
<hr>
<p class="tiny"><b>Last thing!</b> Enter these two words correctly (with spaces) so we know you're not a robot (don't worry robots, we still love you).</p>
<div class="recaptcha">
<%== recaptcha_tag :challenge, ssl: true %>
</div>
<hr>
<h3>You're done. Just click the button below!</h3>
<input class="btn-Action" type="submit" value="Create Home Page">
</form>
</div>
</div>
</main>
<script>
window.onload = function() {
$('#signupform').find(':submit').prop('disabled', false)
$('#signupform').submit(function(event) {
if($('#signupform input:radio[name="plan"]:checked').val() == 'free') {
return true
}
if($('#stripe_token').val() != '')
return true
var planError = $('#plan_error')
planError.css('display', 'none')
var signupform = $(this)
signupform.find(':submit').prop('disabled', true)
Stripe.card.createToken(signupform, function(status, response) {
console.log(response)
if(response.error) {
planError.text(response.error.message)
planError.css('display', 'block')
window.location = '#plan_error_link'
signupform.find(':submit').prop('disabled', false)
return false
} else {
$('#stripe_token').val(response.id)
signupform.submit()
}
})
return false
})
$('#signupform input:radio[name="plan"]').change(function(){
showPlanIfSelected()
})
function showPlanIfSelected() {
var planContainer = $('#plan_container')
if($('#signupform input:radio[name="plan"]:checked').val() == 'supporter')
return planContainer.css('display', 'block')
planContainer.css('display', 'none')
}
showPlanIfSelected()
}
</script>

View file

@ -1,62 +0,0 @@
javascript:
var RecaptchaOptions = {
theme : 'clean'
};
- if !@site.errors.empty?
.row
.span8.offset2
.alert.alert-block.alert-error
p There were errors creating your home page:
- @site.errors.each do |error|
p = error.last.first
.page
.content-Base
.row.content style="padding-top:0"
form method="POST" action="/create"
input name="csrf_token" type="hidden" value="#{csrf_token}"
h2.txt-Center Create a New Home Page
.col.col-50 style="margin:0 auto; float:none"
hr
p.tiny First, enter a username. This will also be used as your site name.<br><b>Do not forget this, it will be used to sign in to and manage your home page.</b> It can only contain letters, numbers, underscores and hyphens, and can only be 32 characters long.
br
h5 Username
p.tiny <input class="input-Area" name="username" type="text" placeholder="yourusername" value="#{@site.username}" autocapitalize="off" autocorrect="off">.neocities.org
hr
p.tiny Next, enter a password. This will be used to allow you to login. Minimum 5 characters. If you don't make it a good password, Dade Murphy from the movie Hackers will come in and steal your "garbage files".
h5 Password
input class="input-Area" name="password" type="password"
br
hr
p.tiny Now you can enter an e-mail address. Your e-mail address is private and we will not show it to anyone for any reason. You don't have to provide one, but <b>we will not be able to reset your password without it, so don't lose your username and password if you leave this blank!</b>
h5 Email
input class="input-Area" name="email" type="email" placeholder="youremail@example.com" value="#{@site.email}"
br
hr
p.tiny You can optionally enter some tags! Tags will allow others to find your site based on your interests, or your site's theme. <b>Separate multiple tags with commas</b>. Don't think too hard about this, you can change them later. You can have a maximum of ten tags, and there is a two word per tag maximum (extra words in a tag will be removed).
h5 Tags
p: input class="input-Area" name="tags" type="text" style="width: 400px; max-width:100%" placeholder="pokemon, video games, bulbasaur" value="#{params[:tags]}" autocapitalize="off" autocorrect="off"
hr
input name="is_nsfw" type="hidden" value="false"
p If your page will contain objectionable (adult) content, check this box:&nbsp;&nbsp;&nbsp;<input name="is_nsfw" type="checkbox" value="true" style="margin-top:0">
hr
p.tiny <b>Last thing!</b> Enter these two words correctly (with spaces) so we know you're not a robot (don't worry robots, we still love you).
div style="background:#fff; width:100%; overflow:auto"
== recaptcha_tag :challenge, ssl: true
br
h3 You're done. Just click the button below!
.txt-Center
input.btn-Action type="submit" value="Create Home Page"