summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/core/actions.py5
-rw-r--r--ranger/defaults/rc.conf2
-rw-r--r--ranger/fsobject/directory.py38
-rw-r--r--ranger/fsobject/fsobject.py3
4 files changed, 46 insertions, 2 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 0fd60b9a..5966789a 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -87,6 +87,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 			self.notify("Aborting: " + item.get_description())
 			self.loader.remove(index=0)
 
+	def get_cumulative_size(self):
+		for f in self.env.get_selection() or ():
+			f.look_up_cumulative_size()
+		self.ui.redraw_main_column()
+
 	def redraw_window(self):
 		"""Redraw the window"""
 		self.ui.redraw_window()
diff --git a/ranger/defaults/rc.conf b/ranger/defaults/rc.conf
index a9e64622..b75c188e 100644
--- a/ranger/defaults/rc.conf
+++ b/ranger/defaults/rc.conf
@@ -216,6 +216,8 @@ map oC chain set sort=ctime;     set sort_reverse=True
 map oA chain set sort=atime;     set sort_reverse=True
 map oT chain set sort="type";    set sort_reverse=True
 
+map dc get_cumulative_size
+
 # Settings
 map zc    toggle_option collapse_preview
 map zd    toggle_option sort_directories_first
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index b3a35a0a..04ed35e0 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -25,6 +25,7 @@ from ranger.fsobject import File, FileSystemObject
 from ranger.core.shared import SettingsAware
 from ranger.ext.accumulator import Accumulator
 from ranger.ext.lazy_property import lazy_property
+from ranger.ext.human_readable import human_readable
 
 def sort_by_basename(path):
 	"""returns path.basename (for sorting)"""
@@ -79,6 +80,8 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
 	content_outdated = False
 	content_loaded = False
 
+	_cumulative_size_calculated = False
+
 	sort_dict = {
 		'basename': sort_by_basename,
 		'natural': sort_naturally,
@@ -185,8 +188,14 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
 				hidden_filter = not self.settings.show_hidden \
 						and self.settings.hidden_filter
 				filelist = os.listdir(mypath)
-				self.size = len(filelist)
-				self.infostring = ' %d' % self.size
+				if not self._cumulative_size_calculated \
+						or self.content_loaded:
+					self.size = len(filelist)
+					self.infostring = ' %d' % self.size
+				if self._cumulative_size_calculated:
+					self._cumulative_size_calculated = False
+				if self.is_link:
+					self.infostring = '->' + self.infostring
 				filenames = [mypath + (mypath == '/' and fname or '/' + fname)\
 						for fname in filelist if accept_file(
 							fname, mypath, hidden_filter, self.filter)]
@@ -327,6 +336,31 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
 		else:
 			self.correct_pointer()
 
+	def _get_cumulative_size(self):
+		if self.size == 0:
+			return 0
+		cum = 0
+		for dirpath, dirnames, filenames in os.walk(self.path,
+				onerror=lambda _: None):
+			for file in filenames:
+				try:
+					if dirpath == self.path:
+						stat = os.stat(os.path.realpath(dirpath + "/" + file))
+					else:
+						stat = os.stat(dirpath + "/" + file)
+					cum += stat.st_size
+				except:
+					pass
+		return cum
+
+	def look_up_cumulative_size(self):
+		if not self._cumulative_size_calculated:
+			self._cumulative_size_calculated = True
+			cum = self._get_cumulative_size()
+			self.size = cum
+			self.infostring = ('-> ' if self.is_link else ' ') + \
+					human_readable(cum)
+
 	@lazy_property
 	def size(self):
 		try:
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index d74b21c1..51e49808 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -117,6 +117,9 @@ class FileSystemObject(FileManagerAware):
 	def use(self):
 		"""Used in garbage-collecting.  Override in Directory"""
 
+	def look_up_cumulative_size(self):
+		pass # normal files have no cumulative size
+
 	def set_mimetype(self):
 		"""assign attributes such as self.video according to the mimetype"""
 		basename = self.basename