experimental support for site tipping integration via paypal or bitcoin

This commit is contained in:
Kyle Drake 2016-12-25 13:40:35 -06:00
parent 119381c222
commit 571e445dc3
10 changed files with 146 additions and 2 deletions

View file

@ -96,6 +96,24 @@ post '/settings/:username/change_name' do
end
end
post '/settings/:username/tipping' do
require_login
require_ownership_for_settings
current_site.tipping_enabled = params[:site][:tipping_enabled]
current_site.tipping_paypal = params[:site][:tipping_paypal]
current_site.tipping_bitcoin = params[:site][:tipping_bitcoin]
if current_site.valid?
current_site.save_changes
flash[:success] = "Tip settings have been updated."
else
flash[:error] = current_site.errors.first.last.first
end
redirect "/settings/#{current_site.username}#tipping"
end
post '/settings/:username/change_nsfw' do
require_login
require_ownership_for_settings

View file

@ -148,6 +148,7 @@ end
get '/site/:username/tip' do |username|
@site = Site[username: username]
redirect request.referrer unless @site.tipping_enabled?
@title = "Tip #{@site.title}"
erb :'tip'
end

49
ext/bitcoin_validator.rb Normal file
View file

@ -0,0 +1,49 @@
class BitcoinValidator
class << self
def address_version
"00"
end
def p2sh_version
"05"
end
def valid_address?(address)
hex = decode_base58(address) rescue nil
return false unless hex && hex.bytesize == 50
return false unless [address_version, p2sh_version].include?(hex[0...2])
base58_checksum?(address)
end
def decode_base58(base58_val)
s = base58_to_int(base58_val).to_s(16); s = (s.bytesize.odd? ? '0'+s : s)
s = '' if s == '00'
leading_zero_bytes = (base58_val.match(/^([1]+)/) ? $1 : '').size
s = ("00"*leading_zero_bytes) + s if leading_zero_bytes > 0
s
end
def base58_checksum?(base58)
hex = decode_base58(base58) rescue nil
return false unless hex
checksum( hex[0...42] ) == hex[-8..-1]
end
def checksum(hex)
b = [hex].pack("H*") # unpack hex
Digest::SHA256.hexdigest( Digest::SHA256.digest(b) )[0...8]
end
def base58_to_int(base58_val)
alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
int_val, base = 0, alpha.size
base58_val.reverse.each_char.with_index do |char,index|
raise ArgumentError, 'Value not a valid Base58 String.' unless char_index = alpha.index(char)
int_val += char_index*(base**index)
end
int_val
end
end
end

View file

@ -0,0 +1,13 @@
Sequel.migration do
up {
DB.add_column :sites, :tipping_enabled, :boolean, default: false
DB.add_column :sites, :tipping_paypal, String
DB.add_column :sites, :tipping_bitcoin, String
}
down {
DB.drop_column :sites, :tipping_enabled
DB.drop_column :sites, :tipping_paypal
DB.drop_column :sites, :tipping_bitcoin
}
end

View file

@ -910,6 +910,14 @@ class Site < Sequel::Model
errors.add :email, 'A valid email address is required.'
end
if !values[:tipping_paypal].blank? && (values[:tipping_paypal] =~ EMAIL_SANITY_REGEX).nil?
errors.add :tipping_paypal, 'A valid PayPal tipping email address is required.'
end
if !values[:tipping_bitcoin].blank? && !BitcoinValidator.valid_address?(values[:tipping_bitcoin])
errors.add :tipping_bitcoin, 'Bitcoin tipping address is not valid.'
end
# Check for existing user
user = self.class.select(:id, :username).filter(username: values[:username]).first

View file

@ -62,6 +62,7 @@
$("a#like").tooltip({html: true})
$("a.comment_like").tooltip({html: true})
$('#shareButton').popover({html: true})
$('#tipButton').popover({html: true})
$('.typeahead').typeahead({
minLength: 2,

View file

@ -27,6 +27,9 @@
<!-- <li><a href="#domain" data-toggle="tab">Domain Name</a></li> -->
<li><a href="#custom_domain" data-toggle="tab">Custom Domain</a></li>
<li><a href="#username" data-toggle="tab">Change Site (User) Name</a></li>
<% if current_site.supporter? %>
<li><a href="#tipping" data-toggle="tab">Tipping</a></li>
<% end %>
<% if @site.admin_nsfw != true %>
<li><a href="#nsfw" data-toggle="tab">18+</a></li>
@ -49,6 +52,9 @@
<div class="tab-pane" id="username">
<%== erb :'settings/site/username' %>
</div>
<div class="tab-pane" id="tipping">
<%== erb :'settings/site/tipping' %>
</div>
<% if @site.admin_nsfw != true %>
<div class="tab-pane" id="nsfw">

View file

@ -0,0 +1,28 @@
<h2>Site Tipping</h2>
<p>
This adds a "Send a Tip" button to your site profile, allowing people to send tips to you for your site. This will send users to PayPal to send money to your account. If you have a Bitcoin address, you can add that too.
</p>
<div>
<form method="POST" action="/settings/<%= current_site.username %>/tipping">
<%== csrf_token_input_html %>
<fieldset>
<input name="site[tipping_enabled]" type="hidden" value="false">
<p style="font-size: 11pt">
Enable Site Tipping: <input name="site[tipping_enabled]" type="checkbox" value="true"
<% if current_site.tipping_enabled == true %>checked<% end %>
>
</p>
<label for="site[tipping_paypal]">PayPal email address:</label>
<input name="site[tipping_paypal]" type="text" placeholder="" class="input-Area" autocapitalize="off" autocorrect="off" value="<%= current_site.tipping_paypal %>" style="width: 400px">
<label for="site[tipping_bitcoin]">Bitcoin address:</label>
<input name="site[tipping_bitcoin]" type="text" placeholder="" class="input-Area" autocapitalize="off" autocorrect="off" value="<%= current_site.tipping_bitcoin %>" style="width: 400px">
</fieldset>
<input class="btn-Action" type="submit" value="Update">
</form>
</div>

View file

@ -54,8 +54,11 @@
<!-- <a href="#" class="btn-Action tip"><span>Tip</span></a> -->
<% end %>
<a href="#" id="shareButton" class="btn-Action" data-container="body" data-toggle="popover" data-placement="bottom" data-content='<%== erb :'_share', layout: false, locals: {site: site} %>'>
<i class="fa fa-share-alt"></i> <span>Share</span></a>
<a href="#" id="shareButton" class="btn-Action" data-container="body" data-toggle="popover" data-placement="bottom" data-content='<%== erb :'_share', layout: false, locals: {site: site} %>'><i class="fa fa-share-alt"></i> <span>Share</span></a>
<% if site.tipping_enabled && (!site.tipping_paypal.blank? || !site.tipping_bitcoin.blank?) %>
<a href="#" id="tipButton" class="btn-Action" data-container="body" data-toggle="popover" data-placement="bottom" data-content='<%== erb :'site/_tip', layout: false, locals: {site: site} %>'><i class="fa fa-usd"></i> <span>Send a Tip</span></a>
<% end %>
</div>
</div>
</div>

17
views/site/_tip.erb Normal file
View file

@ -0,0 +1,17 @@
<% unless site.tipping_paypal.blank? %>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" style="margin-bottom: 0px">
<input type="hidden" name="cmd" value="_donations">
<input type="hidden" name="business" value="<%= site.tipping_paypal %>">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="item_name" value="Site Donation for <%= site.title %>">
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHostedGuest">
<a href="#" onclick="parentNode.submit()">Credit Card</a>
<br>
<a href="#" onclick="parentNode.submit()">PayPal</a>
</form>
<% end %>
<% unless site.tipping_bitcoin.blank? %>
<a href="bitcoin:<%= site.tipping_bitcoin %>?message=<%= Rack::Utils.escape "Site donation for #{site.title}" %>">Bitcoin</a>
<% end %>