admin.rb 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. get '/admin' do
  2. require_admin
  3. @banned_sites = Site.select(:username).filter(is_banned: true).order(:username).all
  4. @nsfw_sites = Site.select(:username).filter(is_nsfw: true).order(:username).all
  5. erb :'admin'
  6. end
  7. get '/admin/reports' do
  8. require_admin
  9. @reports = Report.order(:created_at.desc).all
  10. erb :'admin/reports'
  11. end
  12. get '/admin/site/:username' do |username|
  13. require_admin
  14. @site = Site[username: username]
  15. not_found if @site.nil?
  16. @title = "Site Inspector - #{@site.username}"
  17. erb :'admin/site'
  18. end
  19. post '/admin/reports' do
  20. end
  21. post '/admin/site_files/train' do
  22. require_admin
  23. site = Site[params[:site_id]]
  24. site_file = site.site_files_dataset.where(path: params[:path]).first
  25. not_found if site_file.nil?
  26. site.untrain site_file.path
  27. site.train site_file.path, params[:classifier]
  28. 'ok'
  29. end
  30. get '/admin/usage' do
  31. require_admin
  32. today = Date.today
  33. current_month = Date.new today.year, today.month, 1
  34. @monthly_stats = []
  35. month = current_month
  36. until month.year == 2016 && month.month == 2 do
  37. stats = DB["select sum(views) as views, sum(hits) as hits,sum(bandwidth) as bandwidth from daily_site_stats where created_at::text LIKE '#{month.year}-#{month.strftime('%m')}-%'"].first
  38. stats.keys.each do |key|
  39. stats[key] ||= 0
  40. end
  41. stats.collect {|s| s == 0}.uniq
  42. if stats[:views] != 0 && stats[:hits] != 0 && stats[:bandwidth] != 0
  43. popular_sites = DB[
  44. 'select sum(bandwidth) as bandwidth,username from stats left join sites on sites.id=stats.site_id where stats.created_at >= ? and stats.created_at < ? group by username order by bandwidth desc limit 50',
  45. month,
  46. month.next_month
  47. ].all
  48. @monthly_stats.push stats.merge(date: month).merge(popular_sites: popular_sites)
  49. end
  50. month = month.prev_month
  51. end
  52. erb :'admin/usage'
  53. end
  54. get '/admin/email' do
  55. require_admin
  56. erb :'admin/email'
  57. end
  58. get '/admin/stats' do
  59. require_admin
  60. # expires 14400, :public, :must_revalidate if self.class.production? # 4 hours
  61. @stats = {
  62. total_hosted_site_hits: DB['SELECT SUM(hits) FROM sites'].first[:sum],
  63. total_hosted_site_views: DB['SELECT SUM(views) FROM sites'].first[:sum],
  64. total_site_changes: DB['select max(changed_count) from sites'].first[:max],
  65. total_sites: Site.count
  66. }
  67. # Start with the date of the first created site
  68. start = Site.select(:created_at).
  69. exclude(created_at: nil).
  70. order(:created_at).
  71. first[:created_at].to_date
  72. runner = start
  73. monthly_stats = []
  74. now = Date.today
  75. while Date.new(runner.year, runner.month, 1) <= Date.new(now.year, now.month, 1)
  76. monthly_stats.push(
  77. date: runner,
  78. sites_created: Site.where(created_at: runner..runner.next_month).count,
  79. total_from_start: Site.where(created_at: start..runner.next_month).count,
  80. supporters: Site.where(created_at: start..runner.next_month).exclude(stripe_customer_id: nil).count,
  81. )
  82. runner = runner.next_month
  83. end
  84. @stats[:monthly_stats] = monthly_stats
  85. if $stripe_cache && Time.now < $stripe_cache[:time] + 14400
  86. customers = $stripe_cache[:customers]
  87. else
  88. customers = Stripe::Customer.all limit: 100000
  89. $stripe_cache = {
  90. customers: customers,
  91. time: Time.now
  92. }
  93. end
  94. @stats[:monthly_revenue] = 0.0
  95. subscriptions = []
  96. @stats[:cancelled_subscriptions] = 0
  97. customers.each do |customer|
  98. sub = {created_at: Time.at(customer.created)}
  99. if customer[:subscriptions][:data].empty?
  100. @stats[:cancelled_subscriptions] += 1
  101. next
  102. end
  103. next if customer[:subscriptions][:data].first[:plan][:amount] == 0
  104. sub[:status] = 'active'
  105. plan = customer[:subscriptions][:data].first[:plan]
  106. sub[:amount_without_fees] = (plan[:amount] / 100.0).round(2)
  107. sub[:percentage_fee] = (sub[:amount_without_fees]/(100/2.9)).ceil_to(2)
  108. sub[:fixed_fee] = 0.30
  109. sub[:amount] = sub[:amount_without_fees] - sub[:percentage_fee] - sub[:fixed_fee]
  110. if(plan[:interval] == 'year')
  111. sub[:amount] = (sub[:amount] / 12).round(2)
  112. end
  113. @stats[:monthly_revenue] += sub[:amount]
  114. subscriptions.push sub
  115. end
  116. @stats[:subscriptions] = subscriptions
  117. # Hotwired for now
  118. @stats[:expenses] = 300.0 #/mo
  119. @stats[:percent_until_profit] = (
  120. (@stats[:monthly_revenue].to_f / @stats[:expenses]) * 100
  121. )
  122. @stats[:poverty_threshold] = 11_945
  123. @stats[:poverty_threshold_percent] = (@stats[:monthly_revenue].to_f / ((@stats[:poverty_threshold]/12) + @stats[:expenses])) * 100
  124. # http://en.wikipedia.org/wiki/Poverty_threshold
  125. @stats[:average_developer_salary] = 93_280.00 # google "average developer salary"
  126. @stats[:percent_until_developer_salary] = (@stats[:monthly_revenue].to_f / ((@stats[:average_developer_salary]/12) + @stats[:expenses])) * 100
  127. erb :'admin/stats'
  128. end
  129. post '/admin/email' do
  130. require_admin
  131. %i{subject body}.each do |k|
  132. if params[k].nil? || params[k].empty?
  133. flash[:error] = "#{k.capitalize} is missing."
  134. redirect '/admin/email'
  135. end
  136. end
  137. sites = Site.newsletter_sites
  138. day = 0
  139. until sites.empty?
  140. seconds = 0.0
  141. queued_sites = []
  142. Site::EMAIL_BLAST_MAXIMUM_PER_DAY.times {
  143. break if sites.empty?
  144. queued_sites << sites.pop
  145. }
  146. queued_sites.each do |site|
  147. EmailWorker.perform_at((day.days.from_now + seconds), {
  148. from: 'Kyle from Neocities <kyle@neocities.org>',
  149. to: site.email,
  150. subject: params[:subject],
  151. body: params[:body]
  152. })
  153. seconds += 0.5
  154. end
  155. day += 1
  156. end
  157. flash[:success] = "#{sites.length} emails have been queued, #{Site::EMAIL_BLAST_MAXIMUM_PER_DAY} per day."
  158. redirect '/'
  159. end
  160. post '/admin/banhammer' do
  161. require_admin
  162. if params[:usernames].empty?
  163. flash[:error] = 'no usernames provided'
  164. redirect '/admin'
  165. end
  166. usernames = params[:usernames].split("\n").collect {|u| u.strip}
  167. deleted_count = 0
  168. ip_deleted_count = 0
  169. usernames.each do |username|
  170. next if username == ''
  171. site = Site[username: username]
  172. next if site.nil? || site.is_banned
  173. if !params[:classifier].empty?
  174. site.untrain 'index.html'
  175. site.train 'index.html', params[:classifier]
  176. end
  177. site.ban!
  178. deleted_count += 1
  179. if !params[:ban_using_ips].empty? && IPAddress.valid?(site.ip)
  180. sites = Site.filter(ip: site.ip, is_banned: false).all
  181. sites.each do |s|
  182. next if usernames.include?(s.username)
  183. s.ban!
  184. end
  185. ip_deleted_count += 1
  186. end
  187. if params[:classifier] == 'spam' || params[:classifier] == 'phishing'
  188. next unless IPAddress.valid?(site.ip)
  189. StopForumSpamWorker.perform_async(
  190. username: site.username,
  191. email: site.email,
  192. ip: site.ip,
  193. classifier: params[:classifier]
  194. )
  195. end
  196. end
  197. flash[:success] = "#{ip_deleted_count + deleted_count} sites have been banned, including #{ip_deleted_count} matching IPs."
  198. redirect '/admin'
  199. end
  200. post '/admin/mark_nsfw' do
  201. require_admin
  202. site = Site[username: params[:username]]
  203. if site.nil?
  204. flash[:error] = 'User not found'
  205. redirect '/admin'
  206. end
  207. site.is_nsfw = true
  208. site.admin_nsfw = true
  209. site.save_changes validate: false
  210. flash[:success] = 'MISSION ACCOMPLISHED'
  211. redirect '/admin'
  212. end
  213. post '/admin/feature' do
  214. require_admin
  215. site = Site[username: params[:username]]
  216. if site.nil?
  217. flash[:error] = 'User not found'
  218. redirect '/admin'
  219. end
  220. site.featured_at = Time.now
  221. site.save_changes(validate: false)
  222. flash[:success] = 'Site has been featured.'
  223. redirect '/admin'
  224. end
  225. get '/admin/masquerade/:username' do
  226. require_admin
  227. site = Site[username: params[:username]]
  228. not_found if site.nil?
  229. session[:id] = site.id
  230. redirect '/'
  231. end
  232. def require_admin
  233. redirect '/' unless signed_in? && current_site.is_admin
  234. end