summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2012-08-15 03:31:34 +0200
committerhut <hut@lavabit.com>2012-08-15 03:36:14 +0200
commit3168005e169b64633f8142ff2ccbbae15d44da2a (patch)
tree2aba61dd83c53184274d7e49faad034f0e8f350b
parent23fed83c9afe1938261360cf10efc1bb60f9e5d5 (diff)
downloadranger-3168005e169b64633f8142ff2ccbbae15d44da2a.tar.gz
core.loader: implemented progressbar for CopyLoader
-rw-r--r--ranger/core/loader.py26
-rw-r--r--ranger/ext/shutil_generatorized.py5
2 files changed, 28 insertions, 3 deletions
diff --git a/ranger/core/loader.py b/ranger/core/loader.py
index 58f23821..f1be697a 100644
--- a/ranger/core/loader.py
+++ b/ranger/core/loader.py
@@ -6,6 +6,7 @@ from time import time, sleep
 from subprocess import Popen, PIPE
 from ranger.core.shared import FileManagerAware
 from ranger.ext.signals import SignalDispatcher
+import math
 import os.path
 import sys
 import select
@@ -50,11 +51,31 @@ class CopyLoader(Loadable, FileManagerAware):
 		self.percent = 0
 		if self.copy_buffer:
 			self.one_file = self.copy_buffer[0]
-		Loadable.__init__(self, self.generate(), 'copying/moving...')
+		Loadable.__init__(self, self.generate(), 'Calculating size...')
+
+	def _calculate_size(self, step):
+		from os.path import join
+		size = 0
+		stack = [f.path for f in self.copy_buffer]
+		while stack:
+			fname = stack.pop()
+			if os.path.isdir(fname):
+				stack.extend([join(fname, item) for item in os.listdir(fname)])
+			else:
+				try:
+					fstat = os.stat(fname)
+				except:
+					continue
+				size += max(step, math.ceil(fstat.st_size / step) * step)
+		return size
 
 	def generate(self):
 		from ranger.ext import shutil_generatorized as shutil_g
 		if self.copy_buffer:
+			# TODO: Don't calculate size when renaming (needs detection)
+			bytes_per_tick = shutil_g.BLOCK_SIZE
+			size = max(1, self._calculate_size(bytes_per_tick))
+			bar_tick = 100.0 / (float(size) / bytes_per_tick)
 			if self.do_cut:
 				self.original_copy_buffer.clear()
 				if len(self.copy_buffer) == 1:
@@ -65,6 +86,7 @@ class CopyLoader(Loadable, FileManagerAware):
 					for _ in shutil_g.move(src=f.path,
 							dst=self.original_path,
 							overwrite=self.overwrite):
+						self.percent += bar_tick
 						yield
 			else:
 				if len(self.copy_buffer) == 1:
@@ -77,11 +99,13 @@ class CopyLoader(Loadable, FileManagerAware):
 								dst=os.path.join(self.original_path, f.basename),
 								symlinks=True,
 								overwrite=self.overwrite):
+							self.percent += bar_tick
 							yield
 					else:
 						for _ in shutil_g.copy2(f.path, self.original_path,
 								symlinks=True,
 								overwrite=self.overwrite):
+							self.percent += bar_tick
 							yield
 			cwd = self.fm.get_directory(self.original_path)
 			cwd.load_content()
diff --git a/ranger/ext/shutil_generatorized.py b/ranger/ext/shutil_generatorized.py
index 436d2cb7..72b8dc26 100644
--- a/ranger/ext/shutil_generatorized.py
+++ b/ranger/ext/shutil_generatorized.py
@@ -11,10 +11,11 @@ import sys
 import stat
 from os.path import abspath
 
-__all__ = ["copyfileobj","copyfile","copystat","copy2",
+__all__ = ["copyfileobj","copyfile","copystat","copy2","BLOCK_SIZE",
            "copytree","move","rmtree","Error", "SpecialFileError"]
 
 APPENDIX = '_'
+BLOCK_SIZE = 16 * 1024
 
 class Error(EnvironmentError):
     pass
@@ -28,7 +29,7 @@ try:
 except NameError:
     WindowsError = None
 
-def copyfileobj(fsrc, fdst, length=16*1024):
+def copyfileobj(fsrc, fdst, length=BLOCK_SIZE):
     """copy data from file-like object fsrc to file-like object fdst"""
     while 1:
         buf = fsrc.read(length)
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339