about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/admin/instances_controller.rb15
-rw-r--r--app/models/account.rb1
-rw-r--r--app/views/admin/instances/index.html.haml15
-rw-r--r--config/locales/en.yml4
-rw-r--r--config/navigation.rb1
-rw-r--r--config/routes.rb1
-rw-r--r--spec/controllers/admin/instances_controller_spec.rb15
-rw-r--r--spec/models/account_spec.rb14
8 files changed, 66 insertions, 0 deletions
diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
new file mode 100644
index 000000000..b8f170ec2
--- /dev/null
+++ b/app/controllers/admin/instances_controller.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Admin
+  class InstancesController < BaseController
+    def index
+      @instances = ordered_instances.page(params[:page])
+    end
+
+    private
+
+    def ordered_instances
+      Account.remote.by_domain_accounts
+    end
+  end
+end
diff --git a/app/models/account.rb b/app/models/account.rb
index 2a10f8345..f8a6dd703 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -68,6 +68,7 @@ class Account < ApplicationRecord
   scope :suspended, -> { where(suspended: true) }
   scope :recent, -> { reorder(id: :desc) }
   scope :alphabetic, -> { order(domain: :asc, username: :asc) }
+  scope :by_domain_accounts, -> { group(:domain).select(:domain, 'COUNT(*) AS accounts_count').order('accounts_count desc') }
 
   def follow!(other_account)
     active_relationships.where(target_account: other_account).first_or_create!(target_account: other_account)
diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml
new file mode 100644
index 000000000..b5ad40ac6
--- /dev/null
+++ b/app/views/admin/instances/index.html.haml
@@ -0,0 +1,15 @@
+- content_for :page_title do
+  = t('admin.instances.title')
+
+%table.table
+  %thead
+    %tr
+      %th= t('admin.instances.domain_name')
+      %th= t('admin.instances.account_count')
+  %tbody
+    - @instances.each do |instance|
+      %tr
+        %td= instance.domain
+        %td= instance.accounts_count
+
+= paginate @instances
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2d88bee94..c30e76993 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -114,6 +114,10 @@ en:
         undo: Undo
       title: Domain Blocks
       undo: Undo
+    instances:
+      account_count: Accounts
+      domain_name: Domain name
+      title: Instances
     pubsubhubbub:
       callback_url: Callback URL
       confirmed: Confirmed
diff --git a/config/navigation.rb b/config/navigation.rb
index 7470fea8c..a3f752e47 100644
--- a/config/navigation.rb
+++ b/config/navigation.rb
@@ -17,6 +17,7 @@ SimpleNavigation::Configuration.run do |navigation|
     primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), admin_reports_url, if: proc { current_user.admin? } do |admin|
       admin.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_url, highlights_on: %r{/admin/reports}
       admin.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts}
+      admin.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url, highlights_on: %r{/admin/instances}
       admin.item :pubsubhubbubs, safe_join([fa_icon('paper-plane-o fw'), t('admin.pubsubhubbub.title')]), admin_pubsubhubbub_index_url
       admin.item :domain_blocks, safe_join([fa_icon('lock fw'), t('admin.domain_blocks.title')]), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks}
       admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }
diff --git a/config/routes.rb b/config/routes.rb
index 4bb3393b8..fef5bf916 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -80,6 +80,7 @@ Rails.application.routes.draw do
     resources :pubsubhubbub, only: [:index]
     resources :domain_blocks, only: [:index, :new, :create, :show, :destroy]
     resources :settings, only: [:index, :update]
+    resources :instances, only: [:index]
 
     resources :reports, only: [:index, :show, :update] do
       resources :reported_statuses, only: :destroy
diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb
new file mode 100644
index 000000000..c50ea352f
--- /dev/null
+++ b/spec/controllers/admin/instances_controller_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+RSpec.describe Admin::InstancesController, type: :controller do
+  before do
+    sign_in Fabricate(:user, admin: true), scope: :user
+  end
+
+  describe 'GET #index' do
+    it 'returns http success' do
+      get :index
+
+      expect(response).to have_http_status(:success)
+    end
+  end
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index c39e7986e..3edbc3253 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -410,6 +410,20 @@ RSpec.describe Account, type: :model do
       end
     end
 
+    describe 'by_domain_accounts' do
+      it 'returns accounts grouped by domain sorted by accounts' do
+        2.times { Fabricate(:account, domain: 'example.com') }
+        Fabricate(:account, domain: 'example2.com')
+
+        results = Account.by_domain_accounts
+        expect(results.length).to eq 2
+        expect(results.first.domain).to eq 'example.com'
+        expect(results.first.accounts_count).to eq 2
+        expect(results.last.domain).to eq 'example2.com'
+        expect(results.last.accounts_count).to eq 1
+      end
+    end
+
     describe 'local' do
       it 'returns an array of accounts who do not have a domain' do
         account_1 = Fabricate(:account, domain: nil)