diff --git a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
index a5da039ed95..a54079349e0 100644
--- a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
@@ -24,7 +24,7 @@ export default Discourse.Route.extend({
c.set('top_referrers', topReferrers);
}
- ['admins', 'moderators', 'blocked', 'suspended', 'top_traffic_sources', 'top_referred_topics', 'updated_at'].forEach(function(x) {
+ ['disk_space','admins', 'moderators', 'blocked', 'suspended', 'top_traffic_sources', 'top_referred_topics', 'updated_at'].forEach(function(x) {
c.set(x, d[x]);
});
diff --git a/app/assets/javascripts/admin/templates/dashboard.hbs b/app/assets/javascripts/admin/templates/dashboard.hbs
index a2e8479f92b..fd345aaedd0 100644
--- a/app/assets/javascripts/admin/templates/dashboard.hbs
+++ b/app/assets/javascripts/admin/templates/dashboard.hbs
@@ -100,6 +100,28 @@
{{/unless}}
+
+
+
+
+ |
+ |
+ |
+ |
+
+
+
+ {{#unless loading}}
+
+ {{i18n 'admin.dashboard.uploads'}} |
+ {{disk_space.uploads_used}} ({{i18n 'admin.dashboard.space_free' size=disk_space.uploads_free}}) |
+ {{i18n 'admin.dashboard.backups'}} |
+ {{disk_space.backups_used}} ({{i18n 'admin.dashboard.space_free' size=disk_space.backups_free}} free) |
+
+ {{/unless}}
+
+
+
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index b27a1d04a20..d7250ca8262 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -1,7 +1,10 @@
+require 'disk_space'
class Admin::DashboardController < Admin::AdminController
def index
dashboard_data = AdminDashboardData.fetch_cached_stats || Jobs::DashboardStats.new.execute({})
dashboard_data.merge!({version_check: DiscourseUpdates.check_version.as_json}) if SiteSetting.version_checks?
+
+ dashboard_data[:disk_space] = DiskSpace.cached_stats
render json: dashboard_data
end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 6988d9a55ef..351081698e3 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1531,6 +1531,9 @@ en:
suspended: 'Suspended:'
private_messages_short: "PMs"
private_messages_title: "Private Messages"
+ space_free: "{{size}} free"
+ uploads: "uploads"
+ backups: "backups"
reports:
today: "Today"
diff --git a/lib/disk_space.rb b/lib/disk_space.rb
new file mode 100644
index 00000000000..2a01dae6a3a
--- /dev/null
+++ b/lib/disk_space.rb
@@ -0,0 +1,65 @@
+class DiskSpace
+
+ extend ActionView::Helpers::NumberHelper
+
+ def self.uploads_used_bytes
+ used(uploads_path)
+ end
+
+ def self.uploads_free_bytes
+ free(uploads_path)
+ end
+
+ def self.backups_used_bytes
+ used(backups_path)
+ end
+
+ def self.backups_free_bytes
+ free(backups_path)
+ end
+
+ def self.backups_path
+ Backup.base_directory
+ end
+
+ def self.uploads_path
+ "#{Rails.root}/public/uploads/#{RailsMultisite::ConnectionManagement.current_db}"
+ end
+
+ def self.stats
+ {
+ uploads_used: number_to_human_size(uploads_used_bytes),
+ uploads_free: number_to_human_size(uploads_free_bytes),
+ backups_used: number_to_human_size(backups_used_bytes),
+ backups_free: number_to_human_size(backups_free_bytes)
+ }
+ end
+
+ def self.cached_stats
+ stats = $redis.get('disk_space_stats')
+ updated_at = $redis.get('disk_space_stats_updated')
+
+ unless updated_at && (Time.now.to_i - updated_at.to_i) < 30.minutes
+ Scheduler::Defer.later "updated stats" do
+ $redis.set('disk_space_stats_updated', Time.now.to_i)
+ $redis.set('disk_space_stats', self.stats.to_json)
+ end
+ end
+
+ if stats
+ JSON.parse(stats)
+ end
+
+ end
+
+ protected
+
+ def self.free(path)
+ `df -Pk #{path} | awk 'NR==2 {print $4 * 1024;}'`.to_i
+ end
+
+ def self.used(path)
+ `du -s #{path}`.to_i * 1024
+ end
+
+end