From 526f4c9543be1e8aac074686f045f9c2d3bb7f69 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Fri, 10 Apr 2015 18:31:43 -0700 Subject: [PATCH 001/122] add migrations --- migrations/057_add_paypal_data.rb | 11 +++++++++++ migrations/058_add_paypal_status.rb | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 migrations/057_add_paypal_data.rb create mode 100644 migrations/058_add_paypal_status.rb diff --git a/migrations/057_add_paypal_data.rb b/migrations/057_add_paypal_data.rb new file mode 100644 index 00000000..684d637a --- /dev/null +++ b/migrations/057_add_paypal_data.rb @@ -0,0 +1,11 @@ +Sequel.migration do + up { + DB.add_column :sites, :paypal_profile_id, String + DB.add_column :sites, :paypal_token, String + } + + down { + DB.drop_column :sites, :paypal_profile_id + DB.drop_column :sites, :paypal_token + } +end diff --git a/migrations/058_add_paypal_status.rb b/migrations/058_add_paypal_status.rb new file mode 100644 index 00000000..12391a22 --- /dev/null +++ b/migrations/058_add_paypal_status.rb @@ -0,0 +1,9 @@ +Sequel.migration do + up { + DB.add_column :sites, :paypal_active, :boolean, default: false + } + + down { + DB.drop_column :sites, :paypal_active + } +end From 0acbcbb235dd1df22ed2085e0e45ec3940cc64e5 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Wed, 15 Apr 2015 15:27:24 -0700 Subject: [PATCH 002/122] fix copy on plan info --- views/plan/_pricing.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/plan/_pricing.erb b/views/plan/_pricing.erb index 6eda3f0f..2a4b2ca9 100644 --- a/views/plan/_pricing.erb +++ b/views/plan/_pricing.erb @@ -134,7 +134,7 @@ It's safe. We use Stripe for payments, and never store your credit card information directly.
  • - It's affordable. As low as $<%= Site::PLAN_FEATURES[:supporter][:price] %>/month (billed once every year). Higher tiers are optional (and appreciated!) + It's affordable, only $<%= Site::PLAN_FEATURES[:supporter][:price] %> per month.
  • You can cancel or change plans anytime. If you do, we'll refund or credit the amount you didn't use. From 8b32946b19cd66bf5b09be1a7c32b7be1626947d Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sat, 18 Apr 2015 18:48:38 -0700 Subject: [PATCH 003/122] Quick fix to pricing bullet --- views/plan/_pricing.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/plan/_pricing.erb b/views/plan/_pricing.erb index 2a4b2ca9..a6ffac10 100644 --- a/views/plan/_pricing.erb +++ b/views/plan/_pricing.erb @@ -134,7 +134,7 @@ It's safe. We use Stripe for payments, and never store your credit card information directly.
  • - It's affordable, only $<%= Site::PLAN_FEATURES[:supporter][:price] %> per month. + It's affordable. Only $<%= Site::PLAN_FEATURES[:supporter][:price] %> per month.
  • You can cancel or change plans anytime. If you do, we'll refund or credit the amount you didn't use. From eba8a307bd952a5df9686a7f74dcc4c9187687e3 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sat, 18 Apr 2015 18:50:51 -0700 Subject: [PATCH 004/122] Add GeoIP, will be used for stats --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index b5a3e08c..3aaebd78 100644 --- a/Gemfile +++ b/Gemfile @@ -26,6 +26,7 @@ gem 'thread' gem 'scrypt' gem 'rack-cache' gem 'rest-client' +gem 'geoip' platform :mri, :rbx do gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic diff --git a/Gemfile.lock b/Gemfile.lock index e726b123..b3d69511 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -62,6 +62,7 @@ GEM ffi (>= 1.0.0) rake filesize (0.0.3) + geoip (1.5.0) google-api-client (0.7.1) addressable (>= 2.3.2) autoparse (>= 0.3.3) @@ -242,6 +243,7 @@ DEPENDENCIES fabrication faker filesize + geoip google-api-client hiredis jdbc-postgres From ec4a3b444003d580278f334492d08bdfb320c506 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 19 Apr 2015 06:51:40 -0700 Subject: [PATCH 005/122] More signup reporting --- app_helpers.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app_helpers.rb b/app_helpers.rb index 638f1c48..7a1ea067 100644 --- a/app_helpers.rb +++ b/app_helpers.rb @@ -41,13 +41,24 @@ end def require_unbanned_ip if session[:banned] || Site.banned_ip?(request.ip) signout - session[:banned] = true - flash[:error] = 'Site creation has been banned due to ToS violation/spam. '+ + session[:banned] = request.ip if !session[:banned] + send_banned_report + flash[:error] = 'Site creation has been banned due to a Terms of Service violation. '+ 'If you believe this to be in error, contact the site admin.' return {result: 'error'}.to_json end end +def send_banned_report + EmailWorker.perform_async({ + from: 'web@neocities.org', + reply_to: 'contact@neocities.org', + to: 'errors@neocities.org', + subject: "[Neocities] Ban report", + body: "IP: #{request.ip}\n\nSession: #{session.inspect}\n\nParams:#{params.inspect}" + }) +end + def title out = "Neocities" return out if request.path == '/' From 0552eb88338d6b51f5f7109341b2d1075bce501b Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Wed, 22 Apr 2015 16:50:24 +0000 Subject: [PATCH 006/122] push free space to 100MB --- models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/site.rb b/models/site.rb index a91ab51c..0efc80f7 100644 --- a/models/site.rb +++ b/models/site.rb @@ -103,7 +103,7 @@ class Site < Sequel::Model PLAN_FEATURES[:free] = PLAN_FEATURES[:supporter].merge( name: 'Free', - space: Filesize.from('50MB').to_i, + space: Filesize.from('100MB').to_i, bandwidth: Filesize.from('50GB').to_i, price: 0, unlimited_site_creation: false, From bf59b986311a75213542103ee946646f5b1f7f60 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Wed, 22 Apr 2015 12:36:39 -0700 Subject: [PATCH 007/122] Copy changes --- views/index.erb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/views/index.erb b/views/index.erb index 184b60a7..02b720b0 100644 --- a/views/index.erb +++ b/views/index.erb @@ -210,7 +210,7 @@ - @@ -188,8 +188,10 @@ <% if !current_site.plan_feature(:no_file_restrictions) %> Allowed file types | <% end %> - Download entire site | - Mount your site as a drive on your computer! + Download entire site + <% unless is_education? %> + | Mount your site as a drive on your computer! + <% end %> diff --git a/views/settings/account.erb b/views/settings/account.erb index 223fe031..a6c305c1 100644 --- a/views/settings/account.erb +++ b/views/settings/account.erb @@ -75,4 +75,4 @@ $(document).ready(function() { return location.hash = $(e.target).attr('href').substr(1); }); }); - \ No newline at end of file + From 5d89cb305dcacc953c22527840f75324554e1fc9 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 10 May 2015 00:01:07 -0700 Subject: [PATCH 050/122] browse by supporters --- app/browse.rb | 4 ++++ views/browse.erb | 1 + 2 files changed, 5 insertions(+) diff --git a/app/browse.rb b/app/browse.rb index 1b9c5c4e..13359f41 100644 --- a/app/browse.rb +++ b/app/browse.rb @@ -43,6 +43,10 @@ def browse_sites_dataset end case params[:sort_by] + 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 diff --git a/views/browse.erb b/views/browse.erb index 729e5247..e8078b57 100644 --- a/views/browse.erb +++ b/views/browse.erb @@ -26,6 +26,7 @@
    + @@ -48,7 +49,7 @@
    - <% unless is_education? %> + <% unless is_education? || params[:sort_by] == 'followers' %> From 864903aa1f6a63b605b1a790f8286649ea366f1e Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sat, 6 Jun 2015 22:47:12 -0700 Subject: [PATCH 084/122] remove redundant archive requests from queue --- workers/archive_worker.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/workers/archive_worker.rb b/workers/archive_worker.rb index 63df8a07..d7d0de15 100644 --- a/workers/archive_worker.rb +++ b/workers/archive_worker.rb @@ -1,8 +1,19 @@ +require 'sidekiq/api' + class ArchiveWorker include Sidekiq::Worker - sidekiq_options queue: :archive, retry: 10, backtrace: true + sidekiq_options queue: :archive, retry: 2, backtrace: true def perform(site_id) - Site[site_id].archive! + site = Site[site_id] + return if site.nil? || site.is_banned? + + queue = Sidekiq::Queue.new self.class.sidekiq_options_hash['queue'] + + queue.each do |job| + job.delete if job.args == [site_id] && job.jid != jid + end + + site.archive! end end From 11927f027d9434e8a4233599ff7f37885eed6323 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 7 Jun 2015 03:05:13 -0700 Subject: [PATCH 085/122] patch up space used bug --- models/site.rb | 41 ++++++++++++++++++++++++++++------------ tests/site_file_tests.rb | 13 +++++++++++-- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/models/site.rb b/models/site.rb index 0ea7af86..89e09635 100644 --- a/models/site.rb +++ b/models/site.rb @@ -613,11 +613,6 @@ class Site < Sequel::Model true end - def increment_changed_count - self.changed_count += 1 - save_changes(validate: false) - end - def files_zip zip_name = "neocities-#{username}" @@ -663,8 +658,14 @@ class Site < Sequel::Model path = path[1..path.length] if path[0] == '/' - site_files_dataset.where(path: path).delete - SiteChangeFile.filter(site_id: self.id, filename: path).delete + DB.transaction do + site_file = site_files_dataset.where(path: path).first + if site_file + DB['update sites set space_used=space_used-? where id=?', site_file.size, self.id].first + site_file.delete + end + SiteChangeFile.filter(site_id: self.id, filename: path).delete + end true end @@ -1098,16 +1099,32 @@ class Site < Sequel::Model # array of hashes: filename, tempfile, opts. def store_files(files, opts={}) results = [] + new_size = 0 + html_uploaded = false + files.each do |file| + new_size += file[:tempfile].size + html_uploaded = true if file[:filename].match HTML_REGEX results << store_file(file[:filename], file[:tempfile], file[:opts] || opts) end if results.include? true && opts[:new_install] != true - self.site_changed = true - self.site_updated_at = Time.now - self.updated_at = Time.now - save_changes validate: false - increment_changed_count + time = Time.now + DB['update sites set site_changed=?, site_updated_at=?, updated_at=?, changed_count=changed_count+1, space_used=space_used+? where id=?', + html_uploaded, + time, + time, + new_size, + self.id + ].first + + #self.site_changed = true + #self.site_updated_at = Time.now + #self.updated_at = Time.now + #self.changed_count += 1 + #save_changes validate: false + reload + #SiteChange.record self, relative_path unless opts[:new_install] ArchiveWorker.perform_async self.id end diff --git a/tests/site_file_tests.rb b/tests/site_file_tests.rb index bd2052ab..77278c6f 100644 --- a/tests/site_file_tests.rb +++ b/tests/site_file_tests.rb @@ -24,12 +24,15 @@ describe 'site_files' do describe 'delete' do it 'works' do - upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + upload 'files[]' => uploaded_file + @site.reload.space_used.must_equal uploaded_file.size file_path = @site.files_path 'test.jpg' File.exists?(file_path).must_equal true delete_file filename: 'test.jpg' File.exists?(file_path).must_equal false SiteFile[site_id: @site.id, path: 'test.jpg'].must_be_nil + @site.reload.space_used.must_equal 0 end it 'deletes a directory and all files in it' do @@ -113,7 +116,9 @@ describe 'site_files' do end it 'succeeds with valid file' do - upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + puts uploaded_file.size + upload 'files[]' => uploaded_file last_response.body.must_match /successfully uploaded/i File.exists?(@site.files_path('test.jpg')).must_equal true @@ -121,6 +126,10 @@ describe 'site_files' do queue_args['site'].must_equal @site.username queue_args['path'].must_equal '/test.jpg' + @site.reload + @site.space_used.wont_equal 0 + @site.space_used.must_equal uploaded_file.size + ThumbnailWorker.jobs.length.must_equal 1 ThumbnailWorker.drain From 092eb4536fe792e0e57846d4b27cca1df320ba5a Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 7 Jun 2015 16:27:30 -0700 Subject: [PATCH 086/122] browse pagination length to 100 --- models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/site.rb b/models/site.rb index 89e09635..76fff365 100644 --- a/models/site.rb +++ b/models/site.rb @@ -132,7 +132,7 @@ class Site < Sequel::Model plan_five: 5 } - BROWSE_PAGINATION_LENGTH = 300 + BROWSE_PAGINATION_LENGTH = 100 many_to_many :tags From 397f34a014d9a218bd8cbff8fdb7c8f5425ba15d Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 7 Jun 2015 21:54:25 -0700 Subject: [PATCH 087/122] Fix bug allowing you to delete your own site directory --- app/api.rb | 4 ++++ models/site.rb | 1 + tests/api_tests.rb | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/app/api.rb b/app/api.rb index 1143cee3..57950539 100644 --- a/app/api.rb +++ b/app/api.rb @@ -48,6 +48,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 diff --git a/models/site.rb b/models/site.rb index 76fff365..2b7086c8 100644 --- a/models/site.rb +++ b/models/site.rb @@ -637,6 +637,7 @@ class Site < Sequel::Model end def delete_file(path) + return false if files_path(path) == files_path begin FileUtils.rm files_path(path) rescue Errno::EISDIR diff --git a/tests/api_tests.rb b/tests/api_tests.rb index ca368d75..f12af381 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -107,6 +107,27 @@ describe 'api delete' do res[:error_type].must_equal 'missing_files' end + it 'fails to delete site directory' do + create_site + basic_authorize @user, @pass + post '/api/delete', filenames: ['/'] + res[:error_type].must_equal 'cannot_delete_site_directory' + File.exist?(@site.files_path).must_equal true + end + + it 'fails to delete other directories' do + create_site + @other_site = @site + create_site + basic_authorize @user, @pass + post '/api/delete', filenames: ["../#{@other_site.username}"] + File.exist?(@other_site.base_files_path).must_equal true + res[:error_type].must_equal 'missing_files' + post '/api/delete', filenames: ["../#{@other_site.username}/index.html"] + File.exist?(@other_site.base_files_path+'/index.html').must_equal true + res[:error_type].must_equal 'missing_files' + end + it 'succeeds with valid filenames' do create_site basic_authorize @user, @pass From 784ba447856f4e03bd9412a20d2c8eca39193ac6 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Mon, 8 Jun 2015 20:49:30 -0700 Subject: [PATCH 088/122] Restrict amount of files created per site --- app/api.rb | 4 ++++ app/site_files.rb | 4 ++++ tests/api_tests.rb | 13 +++++++++++++ tests/site_tests.rb | 6 ++++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/api.rb b/app/api.rb index 57950539..1387c659 100644 --- a/app/api.rb +++ b/app/api.rb @@ -23,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" diff --git a/app/site_files.rb b/app/site_files.rb index 80ca6130..aa7107dc 100644 --- a/app/site_files.rb +++ b/app/site_files.rb @@ -124,6 +124,10 @@ post '/site_files/upload' do file_upload_response "File(s) do not fit in your available space, upload cancelled." end + if current_site.too_many_files? params[:files].length + file_upload_response "Too many files, cannot upload" + end + results = current_site.store_files params[:files] file_upload_response end diff --git a/tests/api_tests.rb b/tests/api_tests.rb index f12af381..668589f8 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -160,6 +160,19 @@ describe 'api upload' do res[:error_type].must_equal 'missing_files' end + it 'fails with too many files' do + create_site + basic_authorize @user, @pass + @site.plan_feature(:maximum_site_files).times { + uuid = SecureRandom.uuid.gsub('-', '')+'.html' + @site.add_site_file path: uuid + } + post '/api/upload', { + '/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + } + res[:error_type].must_equal 'too_many_files' + end + it 'resists directory traversal attack' do create_site basic_authorize @user, @pass diff --git a/tests/site_tests.rb b/tests/site_tests.rb index c42d1d49..e72a685e 100644 --- a/tests/site_tests.rb +++ b/tests/site_tests.rb @@ -53,10 +53,12 @@ describe Site do end it 'should match plan_type' do - %w{supporter neko catbus fatcat}.each do |plan_type| + %w{supporter free}.each do |plan_type| site = Fabricate :site, plan_type: plan_type site.plan_type.must_equal plan_type end + site = Fabricate :site, plan_type: nil + site.plan_type.must_equal 'free' end end @@ -77,4 +79,4 @@ describe Site do site.suggestions.length.must_equal Site::SUGGESTIONS_LIMIT end end -end \ No newline at end of file +end From 5b13244712d022c3d634268fe89b1786b6305e24 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Mon, 8 Jun 2015 20:50:02 -0700 Subject: [PATCH 089/122] Site model for file limit fix --- models/site.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/models/site.rb b/models/site.rb index 2b7086c8..6c214361 100644 --- a/models/site.rb +++ b/models/site.rb @@ -102,7 +102,8 @@ class Site < Sequel::Model unlimited_site_creation: true, custom_ssl_certificates: true, no_file_restrictions: true, - custom_domains: true + custom_domains: true, + maximum_site_files: 25000 } PLAN_FEATURES[:free] = PLAN_FEATURES[:supporter].merge( @@ -113,9 +114,14 @@ class Site < Sequel::Model unlimited_site_creation: false, custom_ssl_certificates: false, no_file_restrictions: false, - custom_domains: false + custom_domains: false, + maximum_site_files: 1000 ) + def too_many_files?(file_count=0) + (site_files_dataset.count + file_count) > plan_feature(:maximum_site_files) + end + def plan_feature(key) PLAN_FEATURES[plan_type.to_sym][key.to_sym] end @@ -1103,6 +1109,11 @@ class Site < Sequel::Model new_size = 0 html_uploaded = false + if too_many_files?(files.length) + results << false + return results + end + files.each do |file| new_size += file[:tempfile].size html_uploaded = true if file[:filename].match HTML_REGEX From bf61a5384e477ea7ef243b54ca817bab7f688180 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Mon, 8 Jun 2015 20:50:37 -0700 Subject: [PATCH 090/122] show stats by days --- app/site.rb | 15 ++++++++++++++- views/site/stats.erb | 8 ++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/site.rb b/app/site.rb index 4291edce..32e4e577 100644 --- a/app/site.rb +++ b/app/site.rb @@ -82,8 +82,21 @@ get '/site/:username/stats' do location_hash end - @stats[:stat_days] = @site.stats_dataset.order(:created_at.desc).limit(7).all.reverse + stats_dataset = @site.stats_dataset.order(:created_at.desc) + 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} diff --git a/views/site/stats.erb b/views/site/stats.erb index 3d5b16d7..c907cdd4 100644 --- a/views/site/stats.erb +++ b/views/site/stats.erb @@ -139,10 +139,10 @@ <% if current_site.supporter? %> <% else %>

    (Upgrade to see up to see stats for all time)

    From d3eda71447fd3a69c1690bea39237e3bd0a15e6a Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Mon, 8 Jun 2015 21:07:05 -0700 Subject: [PATCH 091/122] exclude stats from the current day --- app/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/site.rb b/app/site.rb index 32e4e577..d716ec56 100644 --- a/app/site.rb +++ b/app/site.rb @@ -82,7 +82,7 @@ get '/site/:username/stats' do location_hash end - stats_dataset = @site.stats_dataset.order(:created_at.desc) + stats_dataset = @site.stats_dataset.order(:created_at.desc).exclude(created_at: Date.today) if @site.supporter? unless params[:days].to_s == 'sincethebigbang' From b11350b04fe196c8120d1beecaff4f8ede485c64 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Mon, 8 Jun 2015 21:16:54 -0700 Subject: [PATCH 092/122] most followed default browse --- app/browse.rb | 8 +++++--- views/browse.erb | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/browse.rb b/app/browse.rb index 9e7dda14..744e67e7 100644 --- a/app/browse.rb +++ b/app/browse.rb @@ -79,9 +79,11 @@ 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 diff --git a/views/browse.erb b/views/browse.erb index 672b08ef..6fe5da75 100644 --- a/views/browse.erb +++ b/views/browse.erb @@ -25,8 +25,8 @@