Code to display tips submitted on news feed

This commit is contained in:
Kyle Drake 2017-02-07 22:45:29 -08:00
parent 621e45b6a2
commit cc07e90b44
11 changed files with 131 additions and 12 deletions

View file

@ -47,6 +47,7 @@ gem 'image_optim'
gem 'image_optim_pack' gem 'image_optim_pack'
gem 'ipaddress' gem 'ipaddress'
gem 'feedjira' gem 'feedjira'
gem 'monetize'
platform :mri, :rbx do platform :mri, :rbx do
gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic

View file

@ -145,6 +145,11 @@ GEM
mocha (1.1.0) mocha (1.1.0)
metaclass (~> 0.0.1) metaclass (~> 0.0.1)
mock_redis (0.16.1) mock_redis (0.16.1)
monetize (1.6.0)
money (~> 6.8)
money (6.8.1)
i18n (>= 0.6.4, <= 0.7.0)
sixarm_ruby_unaccent (>= 1.1.1, < 2)
msgpack (0.7.5) msgpack (0.7.5)
multi_json (1.12.1) multi_json (1.12.1)
multipart-post (2.0.0) multipart-post (2.0.0)
@ -238,6 +243,7 @@ GEM
sinatra (>= 1.0.0) sinatra (>= 1.0.0)
sinatra-xsendfile (0.4.2) sinatra-xsendfile (0.4.2)
sinatra (>= 0.9.1) sinatra (>= 0.9.1)
sixarm_ruby_unaccent (1.1.1)
slop (3.6.0) slop (3.6.0)
storable (0.8.9) storable (0.8.9)
stripe (1.15.0) stripe (1.15.0)
@ -317,6 +323,7 @@ DEPENDENCIES
minitest-reporters minitest-reporters
mocha mocha
mock_redis mock_redis
monetize
msgpack msgpack
paypal-recurring paypal-recurring
pg pg

View file

@ -15,7 +15,16 @@ get '/activity' do
site = Site.select(:id).where(id: event.site_id).first site = Site.select(:id).where(id: event.site_id).first
actioning_site = Site.select(:id).where(id: event.actioning_site_id).first actioning_site = Site.select(:id).where(id: event.actioning_site_id).first
events.push(event) if !site.is_a_jerk? && !actioning_site.is_a_jerk? && actioning_site.follows_dataset.count > 1 disclude_event = false
disclude_event = true if site.is_a_jerk?
if event.tip_id
disclude_event = true if actioning_site && actioning_site.is_a_jerk?
else
disclude_event = true if actioning_site && (actioning_site.is_a_jerk? || actioning_site.follows_dataset.count < 2)
end
events.push(event) unless disclude_event
end end
initial_site_change_events = Event.global_site_changes_dataset.limit(100).all initial_site_change_events = Event.global_site_changes_dataset.limit(100).all

View file

@ -146,13 +146,6 @@ post '/site/:username/comment' do |username|
redirect request.referrer redirect request.referrer
end 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
post '/site/:site_id/toggle_follow' do |site_id| post '/site/:site_id/toggle_follow' do |site_id|
require_login require_login
content_type :json content_type :json

View file

@ -10,6 +10,57 @@ post '/webhooks/paypal' do
'ok' 'ok'
end end
def valid_paypal_webhook_source?
# https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1465&viewlocale=en_US&direct=en
return true if ['127.0.0.1', '173.0.81.1', '173.0.81.33', '66.211.170.66'].include?(request.ip)
false
end
post '/webhooks/paypal/tipping_notify' do
return 403 unless valid_paypal_webhook_source?
payload = JSON.parse Base64.strict_decode64(params[:custom]), symbolize_names: true
site = Site[payload[:site_id]]
@tip_hash = {
message: (params[:memo] ? params[:memo] : nil),
amount: params[:mc_gross],
currency: params[:mc_currency],
fee: params[:mc_fee],
actioning_site: (payload[:actioning_site_id] ? Site[payload[:actioning_site_id]] : nil),
paypal_payer_email: params[:payer_email],
paypal_receiver_email: params[:receiver_email],
paypal_txn_id: params[:txn_id],
created_at: DateTime.strptime(params[:payment_date], "%H:%M:%S %b %e, %Y %Z").to_time
}
@tip = site.add_tip @tip_hash
Event.create(
site_id: @tip.site.id,
actioning_site_id: (@tip.actioning_site ? @tip.actioning_site.id : nil),
tip_id: @tip.id
)
if @tip.actioning_site
subject = "You received a #{@tip.amount_string} tip from #{@tip.actioning_site.username}!"
else
subject = "You received a #{@tip.amount_string} tip!"
end
@tip.site.send_email(
subject: subject,
body: Tilt.new('./views/templates/email/tip_received.erb', pretty: true).render(self)
)
EmailWorker.perform_async({
from: 'web@neocities.org',
to: params[:payer_email],
subject: "You sent a #{@tip.amount_string} tip!",
body: Tilt.new('./views/templates/email/tip_sent.erb', pretty: true).render(self)
})
end
post '/webhooks/stripe' do post '/webhooks/stripe' do
event = JSON.parse request.body.read event = JSON.parse request.body.read
if event['type'] == 'customer.created' if event['type'] == 'customer.created'

View file

@ -3,7 +3,7 @@ class Event < Sequel::Model
many_to_one :site many_to_one :site
many_to_one :follow many_to_one :follow
one_to_one :tip many_to_one :tip
one_to_one :tag one_to_one :tag
many_to_one :site_change many_to_one :site_change
many_to_one :profile_comment many_to_one :profile_comment

View file

@ -1,4 +1,12 @@
class Tip < Sequel::Model class Tip < Sequel::Model
many_to_one :site many_to_one :site
many_to_one :actioning_site, class: :Site many_to_one :actioning_site, class: :Site
end
def amount_string
Monetize.parse("#{currency} #{amount.to_f}").format
end
def fee_string
Monetize.parse("#{currency} #{fee.to_f}").format
end
end

View file

@ -951,8 +951,11 @@ a.tag:hover {
.news-item.update .icon { .news-item.update .icon {
background: #E93250; background: #E93250;
} }
.news-item.tip .title .text .headline, .news-item.tip .title .text .headline a, .news-item.tip .date a {
color: #229954!important;
}
.news-item.tip .icon { .news-item.tip .icon {
background: #FFCC00; background: #229954;
} }
.news-item.follow .icon { .news-item.follow .icon {
background: #3399CC; background: #3399CC;

View file

@ -14,6 +14,49 @@
<% if event.profile_comment_id %> <% if event.profile_comment_id %>
<div class="news-item comment" id="event_<%= event.id %>"> <div class="news-item comment" id="event_<%= event.id %>">
<%== erb :'_news_profile_comment', layout: false, locals: {profile_comment: event.profile_comment, event: event} %> <%== erb :'_news_profile_comment', layout: false, locals: {profile_comment: event.profile_comment, event: event} %>
<% elsif event.tip_id %>
<div class="news-item tip">
<div class="title">
<% actioning_site = event.actioning_site_dataset.select(:id, :username, :title, :domain, :stripe_customer_id).first %>
<% event_site = event.site_dataset.select(:id, :username, :title, :domain, :stripe_customer_id).first %>
<% tip = event.tip %>
<div class="icon">
<% if actioning_site %>
<a href="/site/<%= actioning_site.username %>" title="<%= actioning_site.username %>" class="avatar" style="background-image: url(<%= actioning_site.screenshot_url 'index.html', '50x50' %>);"></a>
<% end %>
</div>
<div class="text">
<div class="headline">
<% if actioning_site %>
<% if current_site && current_site.id == actioning_site.id %>
<a href="/site/<%= current_site.username %>" class="you">You</a>
<% else %>
<a href="/site/<%= actioning_site.username %>" class="user" title="<%= actioning_site.title %>"><i class="fa fa-user"><% if actioning_site.supporter? %><i class="fa fa-heart"></i><% end %></i><%= actioning_site.username %></a>
<% end %>
<% else %>
An anonymous donor
<% end %>
sent a <strong><%= tip.amount_string %></strong> tip to
<% if current_site && event_site.id == current_site.id %>
<a href="/site/<%= current_site.username %>" class="you">you</a>!
<% else %>
<a href="/site/<%= event_site.username %>" class="user" title="<%= event_site.title %>"><i class="fa fa-user"><% if event_site.supporter? %><i class="fa fa-heart"></i><% end %></i><%= event_site.username %></a>!
<% end %>
</div>
<span class="comment"><%= tip.message %></span>
</div>
<span class="date">
<a href="/site/<%= event_site.username %>?event_id=<%= event.id %>"><%= event.created_at.ago %></a>
</span>
</div>
<% elsif event.follow_id %> <% elsif event.follow_id %>
<div class="news-item follow"> <div class="news-item follow">
<div class="title"> <div class="title">

View file

@ -31,7 +31,7 @@
<% follows_count = site.follows_dataset.count %> <% follows_count = site.follows_dataset.count %>
<div class="stat"><strong><%= follows_count.format_large_number %></strong> <span>follower<%= follows_count == 1 ? '' : 's' %></span></div> <div class="stat"><strong><%= follows_count.format_large_number %></strong> <span>follower<%= follows_count == 1 ? '' : 's' %></span></div>
<div class="stat"><strong><%= site.changed_count.format_large_number %></strong> <span>update<%= site.changed_count == 1 ? '' : 's' %></span></div> <div class="stat"><strong><%= site.changed_count.format_large_number %></strong> <span>update<%= site.changed_count == 1 ? '' : 's' %></span></div>
<!-- <div class="stat"><strong><%= site.tips_dataset.count %></strong> <span>tips</span></div> --> <div class="stat"><strong><%= site.tips_dataset.count %></strong> <span>tips</span></div>
</div> </div>
<div class="actions"> <div class="actions">
<% if current_site == site %> <% if current_site == site %>

View file

@ -7,6 +7,10 @@
<input type="hidden" name="no_note" value="0"> <input type="hidden" name="no_note" value="0">
<input type="hidden" name="currency_code" value="USD"> <input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHostedGuest"> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHostedGuest">
<input type="hidden" name="notify_url" value="https://neocities.org/webhooks/paypal/tipping_notify">
<input type="hidden" name="cancel_return" value="<%= request.url %>">
<input type="hidden" name="return" value="<%= request.url %>">
<input type="hidden" name="custom" value="<%= Base64.strict_encode64({site_id: site.id, actioning_site_id: (current_site ? current_site.id : nil)}.to_json) %>">
<a href="#" onclick="parentNode.submit()">Credit Card</a> <a href="#" onclick="parentNode.submit()">Credit Card</a>
<br> <br>
<a href="#" onclick="parentNode.submit()">PayPal</a> <a href="#" onclick="parentNode.submit()">PayPal</a>