initial plan structure, and some misc fixes

This commit is contained in:
Kyle Drake 2014-09-12 14:54:53 -07:00
parent 555e64ac97
commit 86990f3535
10 changed files with 129 additions and 24 deletions

View file

@ -22,6 +22,7 @@ gem 'cocaine'
gem 'zipruby' gem 'zipruby'
gem 'sass', require: nil gem 'sass', require: nil
gem 'dav4rack' gem 'dav4rack'
gem 'filesize'
platform :mri do platform :mri 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

@ -57,6 +57,7 @@ GEM
faraday (0.9.0) faraday (0.9.0)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
ffi (1.9.3) ffi (1.9.3)
filesize (0.0.3)
google-api-client (0.7.1) google-api-client (0.7.1)
addressable (>= 2.3.2) addressable (>= 2.3.2)
autoparse (>= 0.3.3) autoparse (>= 0.3.3)
@ -215,6 +216,7 @@ DEPENDENCIES
erubis erubis
fabrication fabrication
faker faker
filesize
google-api-client google-api-client
hiredis hiredis
jdbc-postgres jdbc-postgres

View file

@ -116,3 +116,11 @@ task :buildssl => [:environment] do
ar.add_buffer 'sslsites.json', payload.to_json ar.add_buffer 'sslsites.json', payload.to_json
end end
end end
desc 'Set existing stripe customers to internal supporter plan'
task :primenewstriperunonlyonce => [:environment] do
Site.exclude(stripe_customer_id: nil).all.each do |site|
site.plan_type = 'supporter'
site.save_changes validate: false
end
end

11
app.rb
View file

@ -348,7 +348,7 @@ post '/tags/add' do
if current_site.valid? if current_site.valid?
current_site.save current_site.save
else else
flash[:errors] = current_site.errors[:tags].first flash[:errors] = current_site.errors.first
end end
redirect request.referer redirect request.referer
@ -713,15 +713,16 @@ end
post '/change_email' do post '/change_email' do
require_login require_login
current_site.email = params[:email]
current_site.email_confirmation_token = SecureRandom.hex 3
current_site.email_confirmed = false
if params[:email] == current_site.email if params[:email] == current_site.email
current_site.errors.add :email, 'You are already using this email address for this account.' current_site.errors.add :email, 'You are already using this email address for this account.'
halt erb(:settings) halt erb(:settings)
end end
current_site.email = params[:email]
current_site.email_confirmation_token = SecureRandom.hex 3
current_site.email_confirmed = false
if current_site.valid? if current_site.valid?
current_site.save_changes current_site.save_changes
send_confirmation_email send_confirmation_email
@ -919,7 +920,7 @@ post %r{\/site_files\/save\/(.+)} do
tempfile.close tempfile.close
if current_site.file_size_too_large? tempfile.size if current_site.file_size_too_large? tempfile.size
halt 'File is too large to fit in your space, it has NOT been saved. Please make a local copy and then try to reduce the size.' halt 'File is too large to fit in your space, it has NOT been saved. You will need to reduce the size or upgrade to a new plan.'
end end
current_site.store_file filename, tempfile current_site.store_file filename, tempfile

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_column :sites, :plan_type, :text
}
down {
DB.drop_column :sites, :plan_type
}
end

View file

@ -78,6 +78,46 @@ class Site < Sequel::Model
COMMENTING_ALLOWED_UPDATED_COUNT = 2 COMMENTING_ALLOWED_UPDATED_COUNT = 2
PLAN_FEATURES = {
fatcat: {
name: 'Fat Cat',
space: Filesize.from('100GB').to_i,
bandwidth: Filesize.from('2TB').to_i,
custom_domains: true,
custom_ssl_certificates: true,
global_cdn: true,
ddos_mitigation: true,
unlimited_site_creation: true,
site_mounting: true,
no_file_restrictions: true
}
}
PLAN_FEATURES[:catbus] = PLAN_FEATURES[:fatcat].merge(
name: 'Cat Bus',
space: Filesize.from('10GB').to_i,
bandwidth: Filesize.from('500GB').to_i
)
PLAN_FEATURES[:supporter] = PLAN_FEATURES[:catbus].merge(
name: 'Supporter',
space: Filesize.from('1GB').to_i,
bandwidth: Filesize.from('100GB').to_i,
unlimited_site_creation: false,
custom_ssl_certificates: false,
no_file_restrictions: false
)
PLAN_FEATURES[:free] = PLAN_FEATURES[:supporter].merge(
name: 'Free',
space: Filesize.from('30MB').to_i,
bandwidth: Filesize.from('10GB').to_i,
custom_domains: false,
global_cdn: false,
ddos_mitigation: false,
site_mounting: false
)
many_to_one :server many_to_one :server
many_to_many :tags many_to_many :tags
@ -383,8 +423,11 @@ class Site < Sequel::Model
if new_title.length < TITLE_MAX if new_title.length < TITLE_MAX
self.title = new_title self.title = new_title
save_changes(validate: false)
end end
self.site_changed = true
save_changes(validate: false)
end end
dirname = pathname.dirname.to_s dirname = pathname.dirname.to_s
@ -408,11 +451,6 @@ class Site < Sequel::Model
SiteChange.record self, relative_path SiteChange.record self, relative_path
if self.site_changed != true
self.site_changed = true
save_changes(validate: false)
end
true true
end end
@ -519,6 +557,11 @@ class Site < Sequel::Model
super super
end end
def email=(email)
@original_email = values[:email] unless new?
super
end
# def after_destroy # def after_destroy
# FileUtils.rm_rf files_path # FileUtils.rm_rf files_path
# super # super
@ -549,11 +592,16 @@ class Site < Sequel::Model
errors.add :email, 'An email address is required.' errors.add :email, 'An email address is required.'
end end
# Check for existing email # Check for existing email if new or changing email.
email_check = self.class.select(:id).filter(email: values[:email]).first if new? || @original_email
email_check = self.class.select(:id).filter(email: values[:email])
email_check.exclude!(id: self.id) unless new?
email_check = email_check.first
if email_check && email_check.id != self.id if email_check && email_check.id != self.id
errors.add :email, 'This email address already exists on Neocities, please use your existing account instead of creating a new one.' errors.add :email, 'This email address already exists on Neocities, please use your existing account instead of creating a new one.'
end end
end
unless values[:email] =~ EMAIL_SANITY_REGEX unless values[:email] =~ EMAIL_SANITY_REGEX
errors.add :email, 'A valid email address is required.' errors.add :email, 'A valid email address is required.'
@ -676,7 +724,7 @@ class Site < Sequel::Model
end end
list.select {|f| f[:is_directory]}.sort_by {|f| f[:name]} + list.select {|f| f[:is_directory]}.sort_by {|f| f[:name]} +
list.select {|f| f[:is_directory] == false}.sort_by{|f| f[:name]} list.select {|f| f[:is_directory] == false}.sort_by{|f| f[:name].downcase}
end end
def file_size_too_large?(size_in_bytes) def file_size_too_large?(size_in_bytes)
@ -719,14 +767,18 @@ class Site < Sequel::Model
!values[:stripe_customer_id].nil? !values[:stripe_customer_id].nil?
end end
# This will return false if they have ended their support plan. # This will return false if they have ended their plan.
def ended_supporter? def ended_supporter?
values[:ended_plan] values[:plan_ended]
end end
def plan_name def plan_name
return 'Free Plan' if !supporter? || (supporter? && ended_supporter?) PLAN_FEATURES[plan_type.to_sym][:name]
'Supporter Plan' end
def plan_type
return 'free' if values[:plan_type].nil?
values[:plan_type]
end end
def latest_events(current_page=1, limit=10) def latest_events(current_page=1, limit=10)

View file

@ -13,7 +13,7 @@ class Tag < Sequel::Model
end end
def self.suggestions(name, limit=3) def self.suggestions(name, limit=3)
Tag.filter(name: /^#{name}/). Tag.filter(name: /^#{name}/i).
order(:name). order(:name).
limit(limit). limit(limit).
all all

View file

@ -9,9 +9,9 @@ end
describe 'site_files' do describe 'site_files' do
describe 'upload' do describe 'upload' do
it 'succeeds with index.html file' do it 'succeeds with index.html file' do
site = Fabricate :site site = Fabricate :site
site.site_changed.must_equal false
PurgeCacheWorker.jobs.clear PurgeCacheWorker.jobs.clear
ScreenshotWorker.jobs.clear ScreenshotWorker.jobs.clear
@ -25,6 +25,7 @@ describe 'site_files' do
args = ScreenshotWorker.jobs.first['args'] args = ScreenshotWorker.jobs.first['args']
args.first.must_equal site.username args.first.must_equal site.username
args.last.must_equal 'index.html' args.last.must_equal 'index.html'
site.reload.site_changed.must_equal true
end end
it 'succeeds with valid file' do it 'succeeds with valid file' do
@ -48,6 +49,8 @@ describe 'site_files' do
Site::THUMBNAIL_RESOLUTIONS.each do |resolution| Site::THUMBNAIL_RESOLUTIONS.each do |resolution|
File.exists?(site.thumbnail_path('test.jpg', resolution)).must_equal true File.exists?(site.thumbnail_path('test.jpg', resolution)).must_equal true
end end
site.site_changed.must_equal false
end end
it 'works with directory path' do it 'works with directory path' do

29
tests/site_tests.rb Normal file
View file

@ -0,0 +1,29 @@
require_relative './environment.rb'
require 'rack/test'
include Rack::Test::Methods
def app
Sinatra::Application
end
describe 'site' do
describe 'plan_name' do
it 'should set to free for missing stripe_customer_id' do
site = Fabricate :site
site.reload.plan_type.must_equal 'free'
end
it 'should be free for no plan_type entry' do
site = Fabricate :site, stripe_customer_id: 'cust_derp'
site.plan_type.must_equal 'free'
end
it 'should match plan_type' do
%w{supporter neko catbus fatcat}.each do |plan_type|
site = Fabricate :site, plan_type: plan_type
site.plan_type.must_equal plan_type
end
end
end
end

View file

@ -58,7 +58,7 @@
$('#shareButton').popover({html: true}) $('#shareButton').popover({html: true})
$('.typeahead').typeahead({ $('.typeahead').typeahead({
minLength: 3, minLength: 2,
highlight: true highlight: true
}, { }, {
name: 'tags', name: 'tags',