summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/fsobject/directory.py4
-rw-r--r--ranger/fsobject/fsobject.py220
-rw-r--r--test/bm_loader.py1
3 files changed, 110 insertions, 115 deletions
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index 60387e7b..930ecb70 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -231,7 +231,6 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 			self.cycle_list = None
 			self.content_loaded = True
-			self.determine_infostring()
 			self.last_update_time = time()
 			self.correct_pointer()
 
@@ -250,7 +249,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 		self.content_outdated = False
 
 		if not self.loading:
-			self.load_once()
+			if not self.loaded:
+				self.load()
 
 			if not self.accessible:
 				self.content_loaded = True
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 6bb8b6ec..63ff85ce 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -15,10 +15,7 @@
 
 CONTAINER_EXTENSIONS = 'rar zip tar gz bz bz2 tgz 7z iso cab'.split()
 
-import stat
-import os
-from stat import S_ISLNK, S_ISCHR, S_ISBLK, S_ISSOCK, S_ISFIFO, \
-		S_ISDIR, S_IXUSR
+from os import access, listdir, lstat, readlink, stat
 from time import time
 from os.path import abspath, basename, dirname, realpath
 from . import BAD_INFO
@@ -28,44 +25,47 @@ from ranger.ext.spawn import spawn
 from ranger.ext.human_readable import human_readable
 
 class FileSystemObject(MimeTypeAware, FileManagerAware):
-	is_file = False
-	is_directory = False
-	content_loaded = False
-	force_load = False
-	path = None
-	basename = None
-	basename_lower = None
-	_shell_escaped_basename = None
-	_filetype = None
-	dirname = None
-	extension = None
-	exists = False
-	accessible = False
-	marked = False
-	tagged = False
-	loaded = False
-	runnable = False
-	is_link = False
-	is_device = False
-	is_socket = False
-	is_fifo = False
-	readlink = None
-	stat = None
-	infostring = None
-	permissions = None
-	size = 0
-
-	last_used = None
+	(_filetype,
+	_shell_escaped_basename,
+	basename,
+	basename_lower,
+	dirname,
+	extension,
+	infostring,
+	last_used,
+	path,
+	permissions,
+	readlink,
+	stat) = (None,) * 12
+
+	(content_loaded,
+	force_load,
+
+	is_device,
+	is_directory,
+	is_file,
+	is_fifo,
+	is_link,
+	is_socket,
+
+	accessible,
+	exists,
+	loaded,
+	marked,
+	runnable,
+	stopped,
+	tagged,
+
+	audio,
+	container,
+	document,
+	image,
+	media,
+	video) = (False,) * 21
 
-	stopped = False
-
-	video = False
-	image = False
-	audio = False
-	media = False
-	document = False
-	container = False
 	mimetype_tuple = ()
+	size = 0
+
 
 	def __init__(self, path, preload=None, path_is_abs=False):
 		MimeTypeAware.__init__(self)
@@ -167,33 +167,6 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		"""Called by directory.mark_item() and similar functions"""
 		self.marked = bool(boolean)
 
-	def determine_infostring(self):
-		self.size = 0
-		if self.is_device:
-			self.infostring = 'dev'
-		elif self.is_fifo:
-			self.infostring = 'fifo'
-		elif self.is_socket:
-			self.infostring = 'sock'
-		elif self.is_directory:
-			try:
-				self.size = len(os.listdir(self.path))  # bite me
-			except OSError:
-				self.infostring = BAD_INFO
-				self.accessible = False
-			else:
-				self.infostring = ' %d' % self.size
-				self.accessible = True
-				self.runnable = True
-		elif self.is_file:
-			if self.stat:
-				self.size = self.stat.st_size
-				self.infostring = ' ' + human_readable(self.size)
-			else:
-				self.infostring = BAD_INFO
-		if self.is_link:
-			self.infostring = '->' + self.infostring
-
 	def load(self):
 		"""
 		reads useful information about the filesystem-object from the
@@ -202,82 +175,102 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 
 		self.loaded = True
 
-		# Get the stat object, either from preload or from os.[l]stat
-		self.stat = None
+		# Get the stat object, either from preload or from [l]stat
+		new_stat = None
+		path = self.path
 		if self.preload:
-			self.stat = self.preload[1]
-			self.is_link = S_ISLNK(self.stat.st_mode)
-			if self.is_link:
-				self.stat = self.preload[0]
+			new_stat = self.preload[1]
+			is_link = (new_stat.st_mode & 0o120000) == 0o120000
+			if is_link:
+				new_stat = self.preload[0]
 			self.preload = None
 		else:
 			try:
-				self.stat = os.lstat(self.path)
+				new_stat = lstat(path)
+				is_link = (new_stat.st_mode & 0o120000) == 0o120000
+				if is_link:
+					new_stat = stat(path)
 			except:
 				pass
-			else:
-				self.is_link = S_ISLNK(self.stat.st_mode)
-				if self.is_link:
-					try:
-						self.stat = os.stat(self.path)
-					except:
-						pass
 
 		# Set some attributes
-		if self.stat:
-			mode = self.stat.st_mode
-			self.is_device = bool(S_ISCHR(mode) or S_ISBLK(mode))
-			self.is_socket = bool(S_ISSOCK(mode))
-			self.is_fifo = bool(S_ISFIFO(mode))
+		if new_stat:
+			mode = new_stat.st_mode
 			self.accessible = True
-			if os.access(self.path, os.F_OK):
+			self.is_device = (mode & 0o060000) == 0o060000
+			self.is_fifo = (mode & 0o010000) == 0o010000
+			self.is_link = is_link
+			self.is_socket = (mode & 0o140000) == 0o140000
+			if access(path, 0):
 				self.exists = True
-				if S_ISDIR(mode):
-					self.runnable = bool(mode & S_IXUSR)
+				if self.is_directory:
+					self.runnable = (mode & 0o0100) == 0o0100
 			else:
 				self.exists = False
 				self.runnable = False
-			if self.is_link:
-				self.realpath = realpath(self.path)
-				self.readlink = os.readlink(self.path)
+			if is_link:
+				self.realpath = realpath(path)
+				self.readlink = readlink(path)
 		else:
 			self.accessible = False
 
-		self.determine_infostring()
+		# Determine infostring
+		if self.is_file:
+			if new_stat:
+				self.size = new_stat.st_size
+				self.infostring = ' ' + human_readable(self.size)
+			else:
+				self.size = 0
+				self.infostring = '?'
+		elif self.is_directory:
+			try:
+				self.size = len(listdir(path))  # bite me
+			except OSError:
+				self.size = 0
+				self.infostring = '?'
+				self.accessible = False
+			else:
+				self.infostring = ' %d' % self.size
+				self.accessible = True
+				self.runnable = True
+		elif self.is_device:
+			self.size = 0
+			self.infostring = 'dev'
+		elif self.is_fifo:
+			self.size = 0
+			self.infostring = 'fifo'
+		elif self.is_socket:
+			self.size = 0
+			self.infostring = 'sock'
+		if self.is_link:
+			self.infostring = '->' + self.infostring
+
+		self.stat = new_stat
 
 	def get_permission_string(self):
 		if self.permissions is not None:
 			return self.permissions
 
-		try:
-			mode = self.stat.st_mode
-		except:
-			return '----??----'
-
-		if S_ISDIR(mode):
+		if self.is_directory:
 			perms = ['d']
-		elif S_ISLNK(mode):
+		elif self.is_link:
 			perms = ['l']
 		else:
 			perms = ['-']
 
-		for who in ("USR", "GRP", "OTH"):
-			for what in "RWX":
-				if mode & getattr(stat, "S_I" + what + who):
-					perms.append(what.lower())
+		mode = self.stat.st_mode
+		test = 0o0400
+		for who in range(3):
+			for what in "rwx":
+				if mode & test:
+					perms.append(what)
 				else:
 					perms.append('-')
+				test >> 1
 
 		self.permissions = ''.join(perms)
 		return self.permissions
 
-	def load_once(self):
-		"""calls load() if it has not been called at least once yet"""
-		if not self.loaded:
-			self.load()
-			return True
-		return False
-
 	def go(self):
 		"""enter the directory if the filemanager is running"""
 		if self.fm:
@@ -289,10 +282,11 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		Calls load() if the currently cached information is outdated
 		or nonexistant.
 		"""
-		if self.load_once():
+		if not self.loaded:
+			self.load()
 			return True
 		try:
-			real_mtime = os.lstat(self.path).st_mtime
+			real_mtime = lstat(self.path).st_mtime
 		except OSError:
 			real_mtime = None
 		if self.stat:
diff --git a/test/bm_loader.py b/test/bm_loader.py
index 4bfc2db9..745e6f3b 100644
--- a/test/bm_loader.py
+++ b/test/bm_loader.py
@@ -127,6 +127,7 @@ class benchmark_load(object):
 				self.loader.work()
 
 
+@skip
 class benchmark_raw_load(object):
 	def __init__(self):
 		SettingsAware.settings = Fake()