fix for site tags referencing followed counts

This commit is contained in:
Kyle Drake 2015-07-18 15:23:01 -07:00
commit d264672b51
114 changed files with 4538 additions and 1052 deletions

View file

@ -5,6 +5,56 @@ get '/admin' do
erb :'admin'
end
get '/admin/reports' do
require_admin
@reports = Report.order(:created_at.desc).all
erb :'admin/reports'
end
get '/admin/email' do
require_admin
erb :'admin/email'
end
post '/admin/email' do
require_admin
%i{subject body}.each do |k|
if params[k].nil? || params[k].empty?
flash[:error] = "#{k.capitalize} is missing."
redirect '/admin/email'
end
end
sites = Site.newsletter_sites
day = 0
until sites.empty?
seconds = 0.0
queued_sites = []
Site::EMAIL_BLAST_MAXIMUM_PER_DAY.times {
break if sites.empty?
queued_sites << sites.pop
}
queued_sites.each do |site|
EmailWorker.perform_at((day.days.from_now + seconds), {
from: 'Kyle from Neocities <kyle@neocities.org>',
to: site.email,
subject: params[:subject],
body: params[:body]
})
seconds += 0.5
end
day += 1
end
flash[:success] = "#{sites.length} emails have been queued, #{Site::EMAIL_BLAST_MAXIMUM_PER_DAY} per day."
redirect '/'
end
post '/admin/banip' do
require_admin
site = Site[username: params[:username]]
@ -18,7 +68,7 @@ post '/admin/banip' do
flash[:error] = 'IP is blank, cannot continue'
redirect '/admin'
end
sites = Site.filter(ip: Site.hash_ip(site.ip), is_banned: false).all
sites = Site.filter(ip: site.ip, is_banned: false).all
sites.each {|s| s.ban!}
flash[:error] = "#{sites.length} sites have been banned."
redirect '/admin'

View file

@ -7,6 +7,7 @@ end
post '/api/upload' do
require_api_credentials
files = []
params.each do |k,v|
next unless v.is_a?(Hash) && v[:tempfile]
@ -22,6 +23,10 @@ post '/api/upload' do
api_error 400, 'too_large', 'files are too large to fit in your space, try uploading smaller (or less) files'
end
if current_site.too_many_files?(files.length)
api_error 400, 'too_many_files', "cannot exceed the maximum site files limit (#{current_site.plan_feature(:maximum_site_files)}), #{current_site.supporter? ? 'please contact support' : 'please upgrade to a supporter account'}"
end
files.each do |file|
if !current_site.okay_to_upload?(file)
api_error 400, 'invalid_file_type', "#{file[:filename]} is not a valid file type (or contains not allowed content) for this site, files have not been uploaded"
@ -32,13 +37,7 @@ post '/api/upload' do
end
end
results = []
files.each do |file|
results << current_site.store_file(file[:filename], file[:tempfile])
end
current_site.increment_changed_count if results.include?(true)
results = current_site.store_files files
api_success 'your file(s) have been successfully uploaded'
end
@ -53,6 +52,10 @@ post '/api/delete' do
api_error 400, 'bad_filename', "#{path} is not a valid filename, canceled deleting"
end
if current_site.files_path(path) == current_site.files_path
api_error 400, 'cannot_delete_site_directory', 'cannot delete the root directory of the site'
end
if !current_site.file_exists?(path)
api_error 400, 'missing_files', "#{path} was not found on your site, canceled deleting"
end

View file

@ -1,17 +1,33 @@
get '/browse/?' do
params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty?
site_dataset = browse_sites_dataset
site_dataset = site_dataset.paginate @current_page, Site::BROWSE_PAGINATION_LENGTH
@page_count = site_dataset.page_count || 1
@sites = site_dataset.all
erb :browse
end
def browse_sites_dataset
@current_page = params[:current_page]
@current_page = @current_page.to_i
@current_page = 1 if @current_page == 0
params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty?
if is_education?
site_dataset = education_sites_dataset
else
site_dataset = browse_sites_dataset
end
site_dataset = site_dataset.paginate @current_page, Site::BROWSE_PAGINATION_LENGTH
@page_count = site_dataset.page_count || 1
@sites = site_dataset.all
if params[:tag]
@title = "Sites tagged #{params[:tag]}"
end
erb :browse
end
def education_sites_dataset
site_dataset = Site.filter is_deleted: false
site_dataset = site_dataset.association_join(:tags).select_all(:sites)
params[:tag] = current_site.tags.first.name
site_dataset.where! ['tags.name = ?', params[:tag]]
end
def browse_sites_dataset
site_dataset = Site.filter(is_deleted: false, is_banned: false, is_crashing: false).filter(site_changed: true)
if current_site
@ -27,6 +43,19 @@ def browse_sites_dataset
end
case params[:sort_by]
when 'followers'
site_dataset = site_dataset.association_left_join :follows
site_dataset.select_all! :sites
site_dataset.select_append! Sequel.lit("count(follows.site_id) AS follow_count")
site_dataset.group! :sites__id
site_dataset.order! :follow_count.desc, :updated_at.desc
when 'supporters'
site_dataset.exclude! plan_type: nil
site_dataset.exclude! plan_type: 'free'
site_dataset.order! :views.desc, :site_updated_at.desc
when 'featured'
site_dataset.exclude! featured_at: nil
site_dataset.order! :featured_at.desc
when 'hits'
site_dataset.where!{views > 100}
site_dataset.order!(:hits.desc, :site_updated_at.desc)
@ -50,16 +79,19 @@ def browse_sites_dataset
params[:sort_by] = 'views'
site_dataset.order!(:views.desc, :site_updated_at.desc)
else
params[:sort_by] = 'last_updated'
site_dataset.where!{views > 100}
site_dataset.order!(:site_updated_at.desc, :views.desc)
site_dataset = site_dataset.association_left_join :follows
site_dataset.select_all! :sites
site_dataset.select_append! Sequel.lit("count(follows.site_id) AS follow_count")
site_dataset.group! :sites__id
site_dataset.order! :follow_count.desc, :updated_at.desc
end
end
site_dataset.where! ['sites.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)]
if params[:tag]
site_dataset = site_dataset.association_join(:tags).select_all(:sites)
site_dataset.inner_join! :sites_tags, :site_id => :id
site_dataset.inner_join! :tags, :id => :sites_tags__tag_id
site_dataset.where! ['tags.name = ?', params[:tag]]
site_dataset.where! ['tags.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)]
end

View file

@ -16,9 +16,11 @@ def new_recaptcha_valid?
end
end
CREATE_MATCH_REGEX = /^username$|^password$|^email$|^new_tags_string$|^is_education$/
post '/create_validate_all' do
content_type :json
fields = params.select {|p| p.match /^username$|^password$|^email$|^new_tags_string$/}
fields = params.select {|p| p.match CREATE_MATCH_REGEX}
site = Site.new fields
@ -33,11 +35,12 @@ end
post '/create_validate' do
content_type :json
if !params[:field].match /^username$|^password$|^email$|^new_tags_string$/
if !params[:field].match CREATE_MATCH_REGEX
return {error: 'not a valid field'}.to_json
end
end
site = Site.new(params[:field] => params[:value])
site.is_education = params[:is_education]
site.valid?
field_sym = params[:field].to_sym
@ -51,14 +54,23 @@ end
post '/create' do
content_type :json
require_unbanned_ip
if banned?(true)
signout
session[:banned] = true if !session[:banned]
flash[:error] = 'There was an error, please <a href="/contact">contact support</a> to log in.'
redirect '/'
end
dashboard_if_signed_in
@site = Site.new(
username: params[:username],
password: params[:password],
email: params[:email],
new_tags_string: params[:tags],
new_tags_string: params[:new_tags_string],
is_education: params[:is_education] == 'true' ? true : false,
ip: request.ip
)
@ -85,4 +97,4 @@ post '/create' do
session[:id] = @site.id
{result: 'ok'}.to_json
end
end

View file

@ -2,6 +2,8 @@ get '/?' do
if current_site
require_login
redirect '/dashboard' if current_site.is_education
@suggestions = current_site.suggestions
@current_page = params[:current_page].to_i
@ -34,7 +36,7 @@ get '/?' do
@sites_count = SimpleCache.get :sites_count
end
erb :index, layout: false
erb :index, layout: :index_layout
end
get '/welcome' do
@ -43,6 +45,11 @@ get '/welcome' do
erb :'welcome', locals: {site: current_site}
end
get '/education' do
redirect '/' if signed_in?
erb :education, layout: :index_layout
end
get '/tutorials' do
erb :'tutorials'
end
@ -68,5 +75,10 @@ get '/press' do
end
get '/legal/?' do
@title = 'Legal Guide to Neocities'
erb :'legal'
end
get '/permanent-web' do
erb :'permanent_web'
end

View file

@ -24,4 +24,9 @@ get '/welcome_mockup' do
require_login
erb :'welcome_mockup', locals: {site: current_site}
end
get '/stats_mockup' do
require_login
erb :'stats_mockup', locals: {site: current_site}
end
# :nocov:

View file

@ -1,5 +1,6 @@
get '/signin/?' do
dashboard_if_signed_in
@title = 'Sign In'
erb :'signin'
end
@ -47,4 +48,4 @@ end
def signout
session[:id] = nil
end
end

View file

@ -9,6 +9,8 @@ get '/site/:username/?' do |username|
# TODO: There should probably be a "this site was deleted" page.
not_found if site.nil? || site.is_banned || site.is_deleted
redirect '/' if site.is_education
@title = site.title
@current_page = params[:current_page]
@ -16,6 +18,7 @@ get '/site/:username/?' do |username|
@current_page = 1 if @current_page == 0
if params[:event_id]
not_found unless params[:event_id].is_integer?
event = Event.select(:id).where(id: params[:event_id]).first
not_found if event.nil?
events_dataset = Event.where(id: params[:event_id]).paginate(1, 1)
@ -29,6 +32,76 @@ get '/site/:username/?' do |username|
erb :'site', locals: {site: site, is_current_site: site == current_site}
end
get '/site/:username/archives' do
require_login
@site = Site[username: params[:username]]
not_found if @site.nil?
redirect request.referrer unless current_site.id == @site.id
@archives = @site.archives_dataset.limit(300).order(:updated_at.desc).all
erb :'site/archives'
end
get '/site/:username/stats' do
@site = Site[username: params[:username]]
not_found if @site.nil?
@title = "Site stats for #{@site.host}"
@stats = {}
%i{referrers locations paths}.each do |stat|
@stats[stat] = @site.send("stat_#{stat}_dataset".to_sym).order(:views.desc).limit(100).all
end
@stats[:locations].collect! do |location|
location_name = ''
location_name += location.city_name if location.city_name
if location.region_name
# Some of the region names are numbers for some reason.
begin
Integer(location.region_name)
rescue
location_name += ', ' unless location_name == ''
location_name += location.region_name
end
end
if location.country_code2 && !$country_codes[location.country_code2].nil?
location_name += ', ' unless location_name == ''
location_name += $country_codes[location.country_code2]
end
location_hash = {name: location_name, views: location.views}
if location.latitude && location.longitude
location_hash.merge! latitude: location.latitude, longitude: location.longitude
end
location_hash
end
stats_dataset = @site.stats_dataset.order(:created_at.desc).exclude(created_at: Date.today)
if @site.supporter?
unless params[:days].to_s == 'sincethebigbang'
if params[:days]
stats_dataset.limit! params[:days]
else
stats_dataset.limit! 7
end
end
else
stats_dataset.limit! 7
end
@stats[:stat_days] = stats_dataset.all.reverse
@multi_tooltip_template = "<%= datasetLabel %> - <%= value %>"
erb :'site/stats', locals: {site: @site}
end
post '/site/:username/set_editor_theme' do
require_login
current_site.editor_theme = params[:editor_theme]

View file

@ -9,32 +9,67 @@ get '/site_files/new' do
redirect '/site_files/new_page'
end
post '/site_files/create_page' do
post '/site_files/create' do
require_login
@errors = []
params[:pagefilename].gsub!(/[^a-zA-Z0-9_\-.]/, '')
params[:pagefilename].gsub!(/\.html$/i, '')
filename = params[:pagefilename] || params[:filename]
if params[:pagefilename].nil? || params[:pagefilename].strip.empty?
@errors << 'You must provide a file name.'
halt erb(:'site_files/new_page')
filename.gsub!(/[^a-zA-Z0-9_\-.]/, '')
redirect_uri = '/dashboard'
redirect_uri += "?dir=#{Rack::Utils.escape params[:dir]}" if params[:dir]
if filename.nil? || filename.strip.empty?
flash[:error] = 'You must provide a file name.'
redirect redirect_uri
end
name = "#{params[:pagefilename]}.html"
name = "#{filename}"
name = "#{params[:dir]}/#{name}" if params[:dir]
name = current_site.scrubbed_path name
if current_site.file_exists?(name)
@errors << %{Web page "#{name}" already exists! Choose another name.}
halt erb(:'site_files/new_page')
flash[:error] = %{Web page "#{name}" already exists! Choose another name.}
redirect redirect_uri
end
current_site.install_new_html_file name
extname = File.extname name
unless extname.match /^\.#{Site::EDITABLE_FILE_EXT}/i
flash[:error] = "Must be an text editable file type (#{Site::VALID_EDITABLE_EXTENSIONS.join(', ')})."
redirect redirect_uri
end
site_file = current_site.site_files_dataset.where(path: name).first
if site_file
flash[:error] = 'File already exists, cannot create.'
redirect redirect_uri
end
if extname.match(/^\.html|^\.htm/i)
current_site.install_new_html_file name
else
file_path = current_site.files_path(name)
FileUtils.touch file_path
File.chmod 0640, file_path
site_file ||= SiteFile.new site_id: current_site.id, path: name
site_file.set_all(
size: 0,
sha1_hash: Digest::SHA1.hexdigest(''),
updated_at: Time.now
)
site_file.save
end
flash[:success] = %{#{name} was created! <a style="color: #FFFFFF; text-decoration: underline" href="/site_files/text_editor/#{name}">Click here to edit it</a>.}
redirect params[:dir] ? "/dashboard?dir=#{Rack::Utils.escape params[:dir]}" : '/dashboard'
redirect redirect_uri
end
def file_upload_response(error=nil)
@ -59,8 +94,22 @@ post '/site_files/upload' do
file_upload_response "Uploaded files were not seen by the server, cancelled. We don't know what's causing this yet. Please contact us so we can help fix it. Thanks!"
end
params[:files].each do |file|
file[:filename] = "#{params[:dir]}/#{file[:filename]}" if params[:dir]
params[:files].each_with_index do |file,i|
dir_name = ''
dir_name = params[:dir] if params[:dir]
unless params[:file_paths].nil? || params[:file_paths].empty? || params[:file_paths].length == 0
file_path = params[:file_paths].select {|file_path|
file[:filename] == Pathname(file_path).basename.to_s
}.first
unless file_path.nil?
dir_name += '/' + Pathname(file_path).dirname.to_s
end
end
file[:filename] = "#{dir_name}/#{file[:filename]}"
if current_site.file_size_too_large? file[:tempfile].size
file_upload_response "#{file[:filename]} is too large, upload cancelled."
end
@ -75,21 +124,23 @@ post '/site_files/upload' do
file_upload_response "File(s) do not fit in your available space, upload cancelled."
end
results = []
params[:files].each do |file|
results << current_site.store_file(file[:filename], file[:tempfile])
if current_site.too_many_files? params[:files].length
file_upload_response "Too many files, cannot upload"
end
current_site.increment_changed_count if results.include?(true)
results = current_site.store_files params[:files]
file_upload_response
end
post '/site_files/delete' do
require_login
current_site.delete_file params[:filename]
flash[:success] = "Deleted #{params[:filename]}."
redirect '/dashboard'
dirname = Pathname(params[:filename]).dirname
dir_query = dirname.nil? || dirname.to_s == '.' ? '' : "?dir=#{Rack::Utils.escape dirname}"
redirect "/dashboard#{dir_query}"
end
get '/site_files/:username.zip' do |username|
@ -147,7 +198,7 @@ post %r{\/site_files\/save\/(.+)} do
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
current_site.store_file filename, tempfile
current_site.store_files [{filename: filename, tempfile: tempfile}]
'ok'
end

View file

@ -2,6 +2,8 @@ get '/stats/?' do
# expires 14400, :public, :must_revalidate if self.class.production? # 4 hours
@stats = {
total_hosted_site_hits: DB['SELECT SUM(hits) FROM sites'].first[:sum],
total_hosted_site_views: DB['SELECT SUM(views) FROM sites'].first[:sum],
total_sites: Site.count,
total_unbanned_sites: Site.where(is_banned: false).count,
total_banned_sites: Site.where(is_banned: true).count,

View file

@ -1,3 +1,23 @@
def stripe_get_site_from_event(event)
customer_id = event['data']['object']['customer']
customer = Stripe::Customer.retrieve customer_id
# Some old accounts only have a username for the desc
desc_split = customer.description.split(' - ')
if desc_split.length == 1
site_where = {username: desc_split.first}
end
if desc_split.last.to_i == 0
site_where = {username: desc_split.first}
else
site_where = {id: desc_split.last}
end
Site.where(site_where).first
end
post '/stripe_webhook' do
event = JSON.parse request.body.read
if event['type'] == 'customer.created'
@ -14,8 +34,7 @@ post '/stripe_webhook' do
end
if event['type'] == 'charge.failed'
site_id = event['data']['object']['description'].split(' - ').last
site = Site[site_id]
site = stripe_get_site_from_event event
EmailWorker.perform_async({
from: 'web@neocities.org',
@ -26,8 +45,7 @@ post '/stripe_webhook' do
end
if event['type'] == 'customer.subscription.deleted'
site_id = event['data']['object']['description'].split(' - ').last
site = Site[site_id]
site = stripe_get_site_from_event event
site.stripe_subscription_id = nil
site.plan_type = nil
site.save_changes validate: false

View file

@ -1,10 +1,12 @@
get '/surf/?' do
@current_page = params[:current_page].to_i || 1
params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty?
site_dataset = browse_sites_dataset
site_dataset = site_dataset.paginate @current_page, 1
@page_count = site_dataset.page_count || 1
@site = site_dataset.first
redirect "/browse?#{Rack::Utils.build_query params}" if @site.nil?
@title = "Surf Mode - #{@site.title}"
erb :'surf', layout: false
end