mirror of
https://github.com/neocities/neocities.git
synced 2025-04-24 17:22:35 +02:00
387 lines
12 KiB
Ruby
387 lines
12 KiB
Ruby
get '/site/:username.rss' do |username|
|
|
site = Site[username: username]
|
|
halt 404 if site.nil? || (current_site && site.is_blocking?(current_site))
|
|
content_type :xml
|
|
site.to_rss
|
|
end
|
|
|
|
get '/site/:username/?' do |username|
|
|
site = Site[username: username]
|
|
# TODO: There should probably be a "this site was deleted" page.
|
|
not_found if site.nil? || site.is_banned || site.is_deleted || (current_site && site.is_blocking?(current_site))
|
|
|
|
redirect '/' if site.is_education
|
|
|
|
redirect site.uri unless site.profile_enabled
|
|
|
|
@title = site.title
|
|
|
|
@page = params[:page]
|
|
@page = 1 if @page.not_an_integer?
|
|
|
|
if params[:event_id]
|
|
not_found if params[:event_id].not_an_integer?
|
|
event = Event.where(id: params[:event_id]).exclude(is_deleted: true).first
|
|
not_found if event.nil?
|
|
event_site = event.site
|
|
event_actioning_site = event.actioning_site
|
|
not_found if current_site && event_site && event_site.is_blocking?(current_site)
|
|
not_found if current_site && event_actioning_site && event_actioning_site.is_blocking?(current_site)
|
|
events_dataset = Event.where(id: params[:event_id]).paginate(1, 1)
|
|
else
|
|
events_dataset = site.latest_events(@page, current_site)
|
|
end
|
|
|
|
@page_count = events_dataset.page_count || 1
|
|
@pagination_dataset = events_dataset
|
|
@latest_events = events_dataset.all
|
|
|
|
meta_robots 'noindex, follow'
|
|
|
|
erb :'site', locals: {site: site, is_current_site: site == current_site}
|
|
end
|
|
|
|
MAX_STAT_POINTS = 30
|
|
get '/site/:username/stats' do
|
|
@default_stat_points = 7
|
|
@site = Site[username: params[:username]]
|
|
not_found if @site.nil? || @site.is_banned || @site.is_deleted || (current_site && @site.is_blocking?(current_site))
|
|
|
|
@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'
|
|
unless params[:days].not_an_integer?
|
|
stats_dataset = stats_dataset.limit params[:days]
|
|
else
|
|
params[:days] = @default_stat_points
|
|
stats_dataset = stats_dataset.limit @default_stat_points
|
|
end
|
|
end
|
|
else
|
|
stats_dataset = stats_dataset.limit @default_stat_points
|
|
end
|
|
|
|
stats = stats_dataset.all.reverse
|
|
|
|
if current_site && @site.owned_by?(current_site) && params[:format] == 'csv'
|
|
content_type 'application/csv'
|
|
attachment "#{current_site.username}-stats.csv"
|
|
|
|
return CSV.generate do |csv|
|
|
csv << ['day', 'hits', 'views', 'bandwidth']
|
|
stats.each do |s|
|
|
csv << [s[:created_at].to_s, s[:hits], s[:views], s[:bandwidth]]
|
|
end
|
|
end
|
|
end
|
|
|
|
if stats.length > MAX_STAT_POINTS
|
|
stats = stats.select.with_index {|a, i| (i % (stats.length / MAX_STAT_POINTS.to_f).round) == 0}
|
|
end
|
|
|
|
@stats[:stat_days] = stats
|
|
@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]
|
|
current_site.save_changes validate: false
|
|
'ok'
|
|
end
|
|
|
|
get '/site/:username/follows' do |username|
|
|
@title = "Sites #{username} follows"
|
|
@site = Site[username: username]
|
|
not_found if @site.nil? || @site.is_deleted || (current_site && (@site.is_blocking?(current_site) || current_site.is_blocking?(@site)))
|
|
|
|
params[:page] ||= "1"
|
|
|
|
@pagination_dataset = @site.followings_dataset.paginate(params[:page].to_i, Site::FOLLOW_PAGINATION_LIMIT)
|
|
erb :'site/follows'
|
|
end
|
|
|
|
get '/site/:username/followers' do |username|
|
|
@title = "Sites that follow #{username}"
|
|
@site = Site[username: username]
|
|
not_found if @site.nil? || @site.is_deleted || (current_site && (@site.is_blocking?(current_site) || current_site.is_blocking?(@site)))
|
|
|
|
params[:page] ||= "1"
|
|
|
|
@pagination_dataset = @site.follows_dataset.paginate(params[:page].to_i, Site::FOLLOW_PAGINATION_LIMIT)
|
|
erb :'site/followers'
|
|
end
|
|
|
|
post '/site/:username/comment' do |username|
|
|
require_login
|
|
|
|
site = Site[username: username]
|
|
|
|
redirect request.referer if current_site && (site.is_blocking?(current_site) || current_site.is_blocking?(site))
|
|
|
|
last_comment = site.profile_comments_dataset.order(:created_at.desc).first
|
|
|
|
if last_comment && last_comment.message == params[:message] && last_comment.created_at > 2.hours.ago
|
|
redirect request.referer
|
|
end
|
|
|
|
if site.profile_comments_enabled == false ||
|
|
params[:message].empty? ||
|
|
params[:message].length > Site::MAX_COMMENT_SIZE ||
|
|
site.is_blocking?(current_site) ||
|
|
current_site.is_blocking?(site) ||
|
|
current_site.commenting_allowed? == false ||
|
|
(current_site.is_a_jerk? && site.id != current_site.id && !site.is_following?(current_site))
|
|
redirect request.referrer
|
|
end
|
|
|
|
site.add_profile_comment(
|
|
actioning_site_id: current_site.id,
|
|
message: params[:message]
|
|
)
|
|
|
|
redirect request.referrer
|
|
end
|
|
|
|
post '/site/:site_id/toggle_follow' do |site_id|
|
|
require_login
|
|
content_type :json
|
|
site = Site[id: site_id]
|
|
return 403 if site.is_blocking?(current_site)
|
|
{result: (current_site.toggle_follow(site) ? 'followed' : 'unfollowed')}.to_json
|
|
end
|
|
|
|
post '/site/create_directory' do
|
|
require_login
|
|
|
|
path = "#{params[:dir] || ''}/#{params[:name]}"
|
|
result = current_site.create_directory path
|
|
|
|
if result != true
|
|
flash[:error] = result
|
|
end
|
|
|
|
redirect "/dashboard?dir=#{Rack::Utils.escape params[:dir]}"
|
|
end
|
|
|
|
get '/site/:username/confirm_email/:token' do
|
|
@title = 'Confirm email'
|
|
|
|
if current_site && current_site.email_confirmed
|
|
return erb(:'site_email_confirmed')
|
|
end
|
|
|
|
site = Site[username: params[:username]]
|
|
|
|
if site.nil?
|
|
return erb(:'site_email_not_confirmed')
|
|
end
|
|
|
|
if site.email_confirmed
|
|
return erb(:'site_email_confirmed')
|
|
end
|
|
|
|
if site.email_confirmation_token == params[:token]
|
|
site.email_confirmation_token = nil
|
|
site.email_confirmation_count = 0
|
|
site.email_confirmed = true
|
|
site.save_changes
|
|
|
|
erb :'site_email_confirmed'
|
|
else
|
|
erb :'site_email_not_confirmed'
|
|
end
|
|
end
|
|
|
|
get '/site/:username/confirm_email' do
|
|
require_login
|
|
@title = 'Confirm your Email Address'
|
|
@fromsettings = session[:fromsettings]
|
|
redirect '/' if current_site.username != params[:username] || !current_site.parent? || current_site.email_confirmed
|
|
erb :'site/confirm_email'
|
|
end
|
|
|
|
post '/site/:username/confirm_email' do
|
|
require_login
|
|
|
|
redirect '/' if current_site.username != params[:username] || !current_site.parent? || current_site.email_confirmed
|
|
|
|
# Update email, resend token
|
|
if params[:email]
|
|
send_confirmation_email @site
|
|
end
|
|
|
|
if params[:token].blank?
|
|
flash[:error] = 'You must enter a valid token.'
|
|
redirect "/site/#{current_site.username}/confirm_email"
|
|
end
|
|
|
|
if current_site.email_confirmation_token == params[:token]
|
|
current_site.email_confirmation_token = nil
|
|
current_site.email_confirmation_count = 0
|
|
current_site.email_confirmed = true
|
|
current_site.save_changes
|
|
|
|
if session[:fromsettings]
|
|
session[:fromsettings] = nil
|
|
flash[:success] = 'Email address changed.'
|
|
redirect '/settings#email'
|
|
end
|
|
|
|
redirect '/tutorial'
|
|
else
|
|
flash[:error] = 'You must enter a valid token.'
|
|
redirect "/site/#{current_site.username}/confirm_email"
|
|
end
|
|
end
|
|
|
|
post '/site/:username/block' do |username|
|
|
require_login
|
|
site = Site[username: username]
|
|
redirect request.referer if current_site.id == site.id
|
|
|
|
current_site.block! site
|
|
|
|
if request.referer.match /\/site\/#{username}/i
|
|
redirect '/'
|
|
else
|
|
redirect request.referer
|
|
end
|
|
end
|
|
|
|
get '/site/:username/unblock' do |username|
|
|
require_login
|
|
site = Site[username: username]
|
|
|
|
if site.nil? || current_site.id == site.id
|
|
redirect request.referer
|
|
end
|
|
|
|
current_site.unblock! site
|
|
redirect request.referer
|
|
end
|
|
|
|
get '/site/:username/confirm_phone' do
|
|
require_login
|
|
redirect '/' unless current_site.phone_verification_needed?
|
|
@title = 'Verify your Phone Number'
|
|
erb :'site/confirm_phone'
|
|
end
|
|
|
|
def restart_phone_verification
|
|
current_site.phone_verification_sent_at = nil
|
|
current_site.phone_verification_sid = nil
|
|
current_site.save_changes validate: false
|
|
redirect "/site/#{current_site.username}/confirm_phone"
|
|
end
|
|
|
|
post '/site/:username/confirm_phone' do
|
|
require_login
|
|
redirect '/' unless current_site.phone_verification_needed?
|
|
|
|
if params[:phone_intl]
|
|
phone = Phonelib.parse params[:phone_intl]
|
|
|
|
if !phone.valid?
|
|
flash[:error] = "Invalid phone number, please try again."
|
|
redirect "/site/#{current_site.username}/confirm_phone"
|
|
end
|
|
|
|
if phone.types.include?(:premium_rate) || phone.types.include?(:shared_cost)
|
|
flash[:error] = 'Neocities does not support this type of number, please use another number.'
|
|
redirect "/site/#{current_site.username}/confirm_phone"
|
|
end
|
|
|
|
current_site.phone_verification_sent_at = Time.now
|
|
current_site.phone_verification_attempts += 1
|
|
|
|
if current_site.phone_verification_attempts > Site::PHONE_VERIFICATION_LOCKOUT_ATTEMPTS
|
|
flash[:error] = 'You have exceeded the number of phone verification attempts allowed.'
|
|
redirect "/site/#{current_site.username}/confirm_phone"
|
|
end
|
|
|
|
current_site.save_changes validate: false
|
|
|
|
verification = $twilio.verify
|
|
.v2
|
|
.services($config['twilio_service_sid'])
|
|
.verifications
|
|
.create(to: phone.e164, channel: 'sms')
|
|
|
|
current_site.phone_verification_sid = verification.sid
|
|
current_site.save_changes validate: false
|
|
|
|
flash[:success] = 'Validation message sent! Check your phone and enter the code below.'
|
|
else
|
|
|
|
restart_phone_verification if current_site.phone_verification_sent_at < Time.now - Site::PHONE_VERIFICATION_EXPIRATION_TIME
|
|
minutes_remaining = ((current_site.phone_verification_sent_at - (Time.now - Site::PHONE_VERIFICATION_EXPIRATION_TIME))/60).round
|
|
|
|
begin
|
|
# Check code
|
|
vc = $twilio.verify
|
|
.v2
|
|
.services($config['twilio_service_sid'])
|
|
.verification_checks
|
|
.create(verification_sid: current_site.phone_verification_sid, code: params[:code])
|
|
|
|
# puts vc.status (pending if failed, approved if it passed)
|
|
if vc.status == 'approved'
|
|
current_site.phone_verified = true
|
|
current_site.save_changes validate: false
|
|
else
|
|
flash[:error] = "Code was not correct, please try again. If the phone number you entered was incorrect, you can re-enter the number after #{minutes_remaining} more minutes have passed."
|
|
end
|
|
|
|
rescue Twilio::REST::RestError => e
|
|
if e.message =~ /60202/
|
|
flash[:error] = "You have exhausted your check attempts. Please try again in #{minutes_remaining} minutes."
|
|
elsif e.message =~ /20404/ # Unable to create record
|
|
restart_phone_verification
|
|
else
|
|
raise e
|
|
end
|
|
end
|
|
end
|
|
|
|
# Will redirect to / automagically if phone was verified
|
|
redirect "/site/#{current_site.username}/confirm_phone"
|
|
end
|