summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2009-11-24 00:41:16 +0100
committerhut <hut@lavabit.com>2009-11-24 00:41:16 +0100
commitfae694a03ebb52888a747010fcb92fa43b33b4a8 (patch)
treeccd0d4e8d6a759eb8086d6a7da80316787b868ea
parent6ca37350f8e6bffe78520fddfc29ca53fa562e87 (diff)
downloadranger-fae694a03ebb52888a747010fcb92fa43b33b4a8.tar.gz
better implementation of directories/files
-rw-r--r--code/directory.py72
-rw-r--r--code/file.py6
-rw-r--r--code/fm.py2
-rw-r--r--code/fsobject.py65
-rw-r--r--test/tc_directory.py74
l---------test/testdir/symlink1
-rw-r--r--test/testdir/textfile.txt4
7 files changed, 157 insertions, 67 deletions
diff --git a/code/directory.py b/code/directory.py
index d50432d2..10ad163c 100644
--- a/code/directory.py
+++ b/code/directory.py
@@ -1,55 +1,45 @@
-class FrozenException(Exception): pass
-class NotLoadedYet(Exception): pass
+import fsobject
+import file
 
-class Directory():
+class Directory(fsobject.FSObject):
 	def __init__(self, path):
-		self.path = path
-		self.accessible = False
-		self.files_loaded = False
+		fsobject.FSObject.__init__(self, path)
+		self.content_loaded = False
 		self.scheduled = False
-		self.files = None
-		self.mtime = None
-		self.exists = True
-
-		self.frozen = False
+		self.enterable = False
 
-	def load_files(self):
+		self.filenames = None
+		self.files = None
+		self.pointed_index = None
+	
+	def load_content(self):
+		self.stop_if_frozen()
+		self.load_if_outdated()
+		self.content_loaded = True
 		import os
-		if self.frozen: raise FrozenException()
-		try:
-			self.mtime = os.path.getmtime(self.path)
-			self.files = os.listdir(self.path)
-			self.exists = True
-			self.accessible = True
-		except OSError:
-			self.files = None
-			self.exists = False
-			self.accessible = False
-
-		self.files_loaded = True
-
-	def clone(self):
-		clone = Directory(self.path)
-		for key in iter(self.__dict__):
-			clone.__dict__[key] = self.__dict__[key]
-		return clone
-
-	def frozenClone(self):
-		clone = self.clone()
-		clone.frozen = True
-		return clone
+		if self.exists:
+			self.filenames = os.listdir(self.path)
+			self.files = []
+			for name in self.filenames:
+				f = file.File(name)
+				f.load()
+				self.files.append(f)
+	
+	def load_content_once(self):
+		self.stop_if_frozen()
+		if not self.content_loaded: self.load_content()
 
 	def __len__(self):
-		if not self.accessible: raise NotLoadedYet()
-		return len(self.files)
+		if not self.accessible: raise fsobject.NotLoadedYet()
+		return len(self.filenames)
 	
 	def __getitem__(self, key):
-		if not self.accessible: raise NotLoadedYet()
-		return self.files[key]
+		if not self.accessible: raise fsobject.NotLoadedYet()
+		return self.filenames[key]
 
 if __name__ == '__main__':
 	d = Directory('.')
-	d.load_files()
-	print(d.files)
+	d.load_filenames()
+	print(d.filenames)
 	print(d[1])
 
diff --git a/code/file.py b/code/file.py
new file mode 100644
index 00000000..291e53b2
--- /dev/null
+++ b/code/file.py
@@ -0,0 +1,6 @@
+import fsobject
+class File(fsobject.FSObject):
+	pass
+#	def __init__(self, path):
+#		fsobject.FSObject.__init__(self, path)
+		
diff --git a/code/fm.py b/code/fm.py
index 8029d915..c2fe30a4 100644
--- a/code/fm.py
+++ b/code/fm.py
@@ -18,7 +18,7 @@ class FM():
 			self.env.pwd = directory.Directory(path)
 			self.env.directories[path] = self.env.pwd
 
-		self.env.pwd.load_files()
+		self.env.pwd.load_content()
 		if len(self.env.pwd) > 0: self.env.cf = self.env.pwd[0]
 
 	def run(self):
diff --git a/code/fsobject.py b/code/fsobject.py
new file mode 100644
index 00000000..d1cd1410
--- /dev/null
+++ b/code/fsobject.py
@@ -0,0 +1,65 @@
+class FrozenException(Exception): pass
+class NotLoadedYet(Exception): pass
+
+class FSObject(object):
+	def __init__(self, path):
+		self.path = path
+		self.exists = False
+		self.accessible = False
+		self.marked = False
+		self.tagged = False
+		self.frozen = False
+		self.loaded = False
+		self.stat = None
+
+	def clone(self):
+		clone = type(self)(self.path)
+		for key in iter(self.__dict__):
+			clone.__dict__[key] = self.__dict__[key]
+		return clone
+
+	def load(self):
+		self.stop_if_frozen()
+		self.loaded = True
+
+		import os
+		try:
+			self.stat = os.stat(self.path)
+			self.exists = True
+			self.accessible = True
+		except OSError:
+			self.exists = False
+			self.accessible = False
+
+	def load_once(self):
+		self.stop_if_frozen()
+		if not self.loaded: self.load()
+
+	def load_if_outdated(self):
+		self.stop_if_frozen()
+		import os
+
+		if not self.loaded:
+			self.load()
+			return True
+
+		real_mtime = os.stat(self.path).st_mtime
+		cached_mtime = self.stat.st_mtime
+
+		if real_mtime != cached_mtime:
+			self.load()
+			return True
+
+		return False
+
+	def frozen_clone(self):
+		self.stop_if_frozen()
+		return self.clone().freeze()
+
+	def stop_if_frozen(self):
+		if self.frozen: raise FrozenException()
+
+	def freeze(self):
+		self.frozen = True
+		return self
+
diff --git a/test/tc_directory.py b/test/tc_directory.py
index b0a4b780..69717ba2 100644
--- a/test/tc_directory.py
+++ b/test/tc_directory.py
@@ -1,9 +1,10 @@
 import unittest
 import sys, os
 sys.path.append('../code')
-import directory
+import directory, fsobject, file
 
 TESTDIR = os.path.realpath(os.path.join(os.path.dirname(sys.argv[0]), 'testdir'))
+TESTFILE = os.path.join(TESTDIR, 'testfile5234148')
 NONEXISTANT_DIR = '/this/directory/will/most/certainly/not/exist'
 
 class Test1(unittest.TestCase):
@@ -12,42 +13,54 @@ class Test1(unittest.TestCase):
 		dir = directory.Directory(TESTDIR)
 
 		self.assertEqual(dir.path, TESTDIR)
-		self.assertFalse(dir.files_loaded)
+		self.assertFalse(dir.content_loaded)
+		self.assertEqual(dir.filenames, None)
 		self.assertEqual(dir.files, None)
-		self.assertRaises(directory.NotLoadedYet, len, dir)
-		self.assertRaises(directory.NotLoadedYet, dir.__getitem__, 0)
+		self.assertRaises(fsobject.NotLoadedYet, len, dir)
+		self.assertRaises(fsobject.NotLoadedYet, dir.__getitem__, 0)
 
-	def testAfterFilesLoaded(self):
-		# Check whether the directory has the correct list of files.
+	def testAfterContentLoaded(self):
+		# Check whether the directory has the correct list of filenames.
 		dir = directory.Directory(TESTDIR)
-		dir.load_files()
+		dir.load_content()
 
 		self.assertTrue(dir.exists)
-		self.assertEqual(type(dir.files), list)
+		self.assertEqual(type(dir.filenames), list)
 
-		# Get the files you expect it to have and sort both before
-		# comparing. I don't expect any order after only loading the files.
-		assumed_files = os.listdir(TESTDIR)
-		assumed_files.sort()
-		dir.files.sort()
+		# Get the filenames you expect it to have and sort both before
+		# comparing. I don't expect any order after only loading the filenames.
+		assumed_filenames = os.listdir(TESTDIR)
+		assumed_filenames.sort()
+		dir.filenames.sort()
 
 		self.assertTrue(len(dir) > 0)
-		self.assertEqual(dir.files, assumed_files)
+		self.assertEqual(dir.filenames, assumed_filenames)
+
+		# build a file object for each file in the list assumed_filenames
+		# and find exactly one equivalent in dir.files
+		for name in assumed_filenames:
+			f = file.File(name)
+			f.load()
+			equal = 0
+			for dirfile in dir.files:
+				if (f.__dict__ == dirfile.__dict__):
+					equal += 1
+			self.assertEqual(equal, 1)
 
 	def testNonexistantDir(self):
 		dir = directory.Directory(NONEXISTANT_DIR)
-		dir.load_files()
+		dir.load_content()
 		
-		self.assertTrue(dir.files_loaded)
+		self.assertTrue(dir.content_loaded)
 		self.assertFalse(dir.exists)
 		self.assertFalse(dir.accessible)
-		self.assertEqual(dir.files, None)
-		self.assertRaises(directory.NotLoadedYet, len, dir)
-		self.assertRaises(directory.NotLoadedYet, dir.__getitem__, 0)
+		self.assertEqual(dir.filenames, None)
+		self.assertRaises(fsobject.NotLoadedYet, len, dir)
+		self.assertRaises(fsobject.NotLoadedYet, dir.__getitem__, 0)
 
 	def testModifyFrozenClone(self):
 		dir = directory.Directory(TESTDIR)
-		clone = dir.frozenClone()
+		clone = dir.frozen_clone()
 
 		# assert that their attributes are equal, except for frozen, which
 		# should be true for the clone.
@@ -56,12 +69,23 @@ class Test1(unittest.TestCase):
 		self.assertEqual(dir.__dict__, clone.__dict__)
 		clone.frozen = True
 
-		# check for inequality after loading files with one object
-		self.assertEqual(dir.files, clone.files)
-		dir.load_files()
-		self.assertNotEqual(dir.files, clone.files)
+		# check for inequality after loading filenames with one object
+		self.assertEqual(dir.filenames, clone.filenames)
+		dir.load_content()
+		self.assertNotEqual(dir.filenames, clone.filenames)
+
+		self.assertRaises(fsobject.FrozenException, clone.load_content)
+
+	def test_load_if_outdated(self):
+		if os.path.exists(TESTFILE): os.unlink(TESTFILE)
+		dir = directory.Directory(TESTDIR)
+		dir.load()
+
+		open(TESTFILE, 'w').close()
+
+		self.assertTrue(dir.load_if_outdated())
 
-		self.assertRaises(directory.FrozenException, clone.load_files)
+		os.unlink(TESTFILE)
 
 unittest.main()
 
diff --git a/test/testdir/symlink b/test/testdir/symlink
new file mode 120000
index 00000000..5cbc1596
--- /dev/null
+++ b/test/testdir/symlink
@@ -0,0 +1 @@
+textfile.txt
\ No newline at end of file
diff --git a/test/testdir/textfile.txt b/test/testdir/textfile.txt
new file mode 100644
index 00000000..45a23497
--- /dev/null
+++ b/test/testdir/textfile.txt
@@ -0,0 +1,4 @@
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.