mirror of
https://github.com/neocities/neocities.git
synced 2025-04-28 11:12:30 +02:00
stats page
This commit is contained in:
parent
8a4e1765f0
commit
7020edc5e7
4 changed files with 164 additions and 18 deletions
4
Gemfile
4
Gemfile
|
@ -1,3 +1,4 @@
|
||||||
|
source 'https://code.stripe.com'
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'sinatra'
|
gem 'sinatra'
|
||||||
|
@ -15,11 +16,10 @@ gem 'mail'
|
||||||
gem 'google-api-client', require: 'google/api_client'
|
gem 'google-api-client', require: 'google/api_client'
|
||||||
gem 'tilt'
|
gem 'tilt'
|
||||||
gem 'erubis'
|
gem 'erubis'
|
||||||
gem 'stripe', :git => 'https://github.com/stripe/stripe-ruby'
|
gem 'stripe'
|
||||||
gem 'screencap'
|
gem 'screencap'
|
||||||
gem 'cocaine'
|
gem 'cocaine'
|
||||||
gem 'zipruby'
|
gem 'zipruby'
|
||||||
gem 'always_verify_ssl_certificates'
|
|
||||||
gem 'sass', require: nil
|
gem 'sass', require: nil
|
||||||
gem 'dav4rack'
|
gem 'dav4rack'
|
||||||
|
|
||||||
|
|
24
Gemfile.lock
24
Gemfile.lock
|
@ -1,13 +1,5 @@
|
||||||
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
|
GEM
|
||||||
|
remote: https://code.stripe.com/
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
activesupport (4.1.4)
|
activesupport (4.1.4)
|
||||||
|
@ -18,7 +10,6 @@ GEM
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
addressable (2.3.6)
|
addressable (2.3.6)
|
||||||
ago (0.1.5)
|
ago (0.1.5)
|
||||||
always_verify_ssl_certificates (0.3.0)
|
|
||||||
ansi (1.4.3)
|
ansi (1.4.3)
|
||||||
autoparse (0.3.3)
|
autoparse (0.3.3)
|
||||||
addressable (>= 2.3.1)
|
addressable (>= 2.3.1)
|
||||||
|
@ -105,6 +96,7 @@ GEM
|
||||||
metaclass (~> 0.0.1)
|
metaclass (~> 0.0.1)
|
||||||
multi_json (1.10.1)
|
multi_json (1.10.1)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
|
netrc (0.7.7)
|
||||||
nokogiri (1.6.3.1)
|
nokogiri (1.6.3.1)
|
||||||
mini_portile (= 0.6.0)
|
mini_portile (= 0.6.0)
|
||||||
pg (0.17.1)
|
pg (0.17.1)
|
||||||
|
@ -146,8 +138,9 @@ GEM
|
||||||
redis (3.0.7)
|
redis (3.0.7)
|
||||||
redis-namespace (1.4.1)
|
redis-namespace (1.4.1)
|
||||||
redis (~> 3.0.4)
|
redis (~> 3.0.4)
|
||||||
rest-client (1.6.7)
|
rest-client (1.7.2)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16, < 3.0)
|
||||||
|
netrc (~> 0.7)
|
||||||
retriable (1.4.1)
|
retriable (1.4.1)
|
||||||
rmagick (2.13.2)
|
rmagick (2.13.2)
|
||||||
safe_yaml (1.0.1)
|
safe_yaml (1.0.1)
|
||||||
|
@ -185,6 +178,10 @@ GEM
|
||||||
sinatra-xsendfile (0.4.2)
|
sinatra-xsendfile (0.4.2)
|
||||||
sinatra (>= 0.9.1)
|
sinatra (>= 0.9.1)
|
||||||
slop (3.5.0)
|
slop (3.5.0)
|
||||||
|
stripe (1.15.0)
|
||||||
|
json (~> 1.8.1)
|
||||||
|
mime-types (>= 1.25, < 3.0)
|
||||||
|
rest-client (~> 1.4)
|
||||||
thread_safe (0.3.4)
|
thread_safe (0.3.4)
|
||||||
tilt (1.4.1)
|
tilt (1.4.1)
|
||||||
timers (1.1.0)
|
timers (1.1.0)
|
||||||
|
@ -211,7 +208,6 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
ago
|
ago
|
||||||
always_verify_ssl_certificates
|
|
||||||
bcrypt
|
bcrypt
|
||||||
capybara_minitest_spec
|
capybara_minitest_spec
|
||||||
cocaine
|
cocaine
|
||||||
|
@ -253,7 +249,7 @@ DEPENDENCIES
|
||||||
sinatra
|
sinatra
|
||||||
sinatra-flash
|
sinatra-flash
|
||||||
sinatra-xsendfile
|
sinatra-xsendfile
|
||||||
stripe!
|
stripe
|
||||||
tilt
|
tilt
|
||||||
webmock
|
webmock
|
||||||
zipruby
|
zipruby
|
||||||
|
|
63
app.rb
63
app.rb
|
@ -149,8 +149,67 @@ get '/tips_mockup' do
|
||||||
erb :'tips_mockup'
|
erb :'tips_mockup'
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/stats_mockup' do
|
get '/stats/?' do
|
||||||
erb :'stats_mockup'
|
require_admin
|
||||||
|
|
||||||
|
@stats = {
|
||||||
|
total_sites: Site.count,
|
||||||
|
total_unbanned_sites: Site.where(is_banned: false).count,
|
||||||
|
total_banned_sites: Site.where(is_banned: true).count,
|
||||||
|
total_nsfw_sites: Site.where(is_nsfw: true).count,
|
||||||
|
total_unbanned_nsfw_sites: Site.where(is_banned: false, is_nsfw: true).count,
|
||||||
|
total_banned_nsfw_sites: Site.where(is_banned: true, is_nsfw: true).count
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start with the date of the first created site
|
||||||
|
|
||||||
|
start = Site.select(:created_at).
|
||||||
|
exclude(created_at: nil).
|
||||||
|
order(:created_at).
|
||||||
|
first[:created_at].to_date
|
||||||
|
|
||||||
|
runner = start
|
||||||
|
|
||||||
|
monthly_stats = []
|
||||||
|
|
||||||
|
now = Time.now
|
||||||
|
|
||||||
|
until runner.year == now.year && runner.month == now.month+1
|
||||||
|
monthly_stats.push(
|
||||||
|
date: runner,
|
||||||
|
sites_created: Site.where(created_at: runner..runner.next_month).count,
|
||||||
|
total_from_start: Site.where(created_at: start..runner.next_month).count,
|
||||||
|
supporters: Site.where(created_at: start..runner.next_month).exclude(stripe_customer_id: nil).count,
|
||||||
|
)
|
||||||
|
|
||||||
|
runner = runner.next_month
|
||||||
|
end
|
||||||
|
|
||||||
|
@stats[:monthly_stats] = monthly_stats
|
||||||
|
|
||||||
|
customers = Stripe::Customer.all
|
||||||
|
|
||||||
|
@stats[:total_recurring_revenue] = 0.0
|
||||||
|
|
||||||
|
subscriptions = []
|
||||||
|
cancelled_subscriptions = 0
|
||||||
|
|
||||||
|
customers.each do |customer|
|
||||||
|
sub = {created_at: Time.at(customer.created)}
|
||||||
|
if customer[:subscriptions]
|
||||||
|
if customer[:subscriptions][:data].empty?
|
||||||
|
sub[:status] = 'cancelled'
|
||||||
|
else
|
||||||
|
sub[:status] = 'active'
|
||||||
|
sub[:amount] = (customer[:subscriptions][:data].first[:plan][:amount] / 100.0).round(2)
|
||||||
|
@stats[:total_recurring_revenue] += sub[:amount]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subscriptions.push sub
|
||||||
|
end
|
||||||
|
|
||||||
|
@stats[:subscriptions] = subscriptions
|
||||||
|
erb :'stats'
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/?' do
|
get '/?' do
|
||||||
|
|
91
views/stats.erb
Normal file
91
views/stats.erb
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<div class="header-Outro">
|
||||||
|
<div class="row content single-Col">
|
||||||
|
<h1>Neocities Site Statistics</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content single-Col misc-page">
|
||||||
|
<h3></h3>
|
||||||
|
<article>
|
||||||
|
<h2>General Stats</h2>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<td>Total Sites</td>
|
||||||
|
<td><%= @stats[:total_sites] %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Unbanned Sites</td>
|
||||||
|
<td><%= @stats[:total_unbanned_sites] %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Banned Sites</td>
|
||||||
|
<td><%= @stats[:total_banned_sites] %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total NSFW Sites</td>
|
||||||
|
<td><%= @stats[:total_nsfw_sites] %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Unbanned NSFW Sites</td>
|
||||||
|
<td><%= @stats[:total_unbanned_nsfw_sites] %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Banned NSFW Sites</td>
|
||||||
|
<td><%= @stats[:total_banned_nsfw_sites] %></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>Monthly Statistics</h2>
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Month</th>
|
||||||
|
<th>Sites Created</th>
|
||||||
|
<th>Change</th>
|
||||||
|
<th>Total</th>
|
||||||
|
<th>Supporters</th>
|
||||||
|
</tr>
|
||||||
|
<% @stats[:monthly_stats].each_with_index do |stat,i| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= stat[:date].year %></td>
|
||||||
|
<td>
|
||||||
|
<%= stat[:date].strftime('%B') %>
|
||||||
|
<% if Time.now.month == stat[:date].month && Time.now.year == stat[:date].year %>
|
||||||
|
<small>current</small>
|
||||||
|
<% end %></td>
|
||||||
|
<td><%= stat[:sites_created] %></td>
|
||||||
|
<td>
|
||||||
|
<% if i != 0 && i != @stats[:monthly_stats].length-1 %>
|
||||||
|
<%= (((stat[:sites_created].to_f - @stats[:monthly_stats][i-1][:sites_created]) / @stats[:monthly_stats][i-1][:sites_created]) * 100).round(2) %>%
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= stat[:total_from_start] %></td>
|
||||||
|
</td>
|
||||||
|
<td><%= stat[:supporters] %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>Subscriptions</h2>
|
||||||
|
<h3>Current Recurring Revenue: <strong><%= format("$%.2f", @stats[:total_recurring_revenue]) %></strong>
|
||||||
|
<br>Active Subscriptions: <strong><%= @stats[:subscriptions].select {|s| s[:status] == 'active' }.length %></strong></h3>
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Date Subscribed</th>
|
||||||
|
</tr>
|
||||||
|
<% @stats[:subscriptions].each do |sub| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= sub[:status] %></td>
|
||||||
|
<td><%= sub[:amount].nil? ? '$0.00' : format("$%.2f", sub[:amount]) %></td>
|
||||||
|
<td><%= sub[:created_at].strftime('%Y %B') %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
Loading…
Add table
Reference in a new issue