further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
authorTero Marttila <terom@fixme.fi>
Fri, 05 Jun 2009 19:28:11 +0300
changeset 55 77abe8dca695
parent 54 cc007b6ab972
child 56 80658a2eebf6
further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
degal/filesystem.py
--- a/degal/filesystem.py	Fri Jun 05 19:27:09 2009 +0300
+++ b/degal/filesystem.py	Fri Jun 05 19:28:11 2009 +0300
@@ -2,7 +2,8 @@
     Filesystem path handling
 """
 
-import os, os.path
+import os, os.path, errno
+import codecs
 
 class Node (object) :
     """
@@ -132,6 +133,31 @@
 
         return os.path.isfile(self.path)
     
+    def path_from (self, node) :
+        """
+            Returns a relative path to this node from the given node
+        """
+
+        XXX
+
+    def stat (self, soft=False) :
+        """
+            Returns the os.stat struct for this node.
+            
+            If `soft` is given, returns None if this node doesn't exist
+        """
+
+        try :
+            return os.stat(self.path)
+
+        except OSError, e :
+            # trap ENOENT for soft
+            if soft and e.errno == errno.ENOENT :
+                return None
+
+            else :
+                raise
+
     def __str__ (self) :
         """
             Returns the raw filesystem path
@@ -191,6 +217,17 @@
         """
         
         return (self.fileext.lower() in ext_list)
+    
+    def open (self, mode='r', encoding=None, errors=None, bufsize=None) :
+        """
+            Wrapper for open/codecs.open
+        """
+
+        if encoding :
+            return codecs.open(self.path, mode, encoding, errors, bufsize)
+
+        else :
+            return open(self.path, mode, bufsize)
 
 class Directory (Node) :
     """
@@ -200,12 +237,18 @@
     # a list of (test_func, node_type) tuples for use by children() to build subnodes with
     NODE_TYPES = None
    
-    def subdir (self, name) :
+    def subdir (self, name, create=False) :
         """
-            Returns a Directory object representing the name underneath this dir
+            Returns a Directory object representing the name underneath this dir.
+
+            If the create option is given, the directory will be created if it does not exist.
         """
 
-        return Directory(self, name=name)
+        dir = Directory(self, name=name)
+        
+        # try and mkdir?
+        if create and not dir.is_dir() :
+            dir.mkdir()
     
     def subfile (self, name) :
         """
@@ -214,6 +257,16 @@
 
         return Directory(self, name=name)
 
+    def mkdir (self) :
+        """
+            Create this directory with default permissions
+            
+            XXX: mode argument
+        """
+        
+        # do it
+        os.mkdir(self.path)
+
     def listdir (self, skip_dotfiles=True) :
         """
             Yield a series of raw fsnames for nodes in this dir
@@ -222,12 +275,22 @@
         # expressed 
         return (fsname for fsname in os.listdir(self.path) if not (skip_dotfiles and fsname.startswith('.')))
 
-    def child_nodes (self, skip_dotfiles=True) :
+    def subnodes (self, skip_dotfiles=True, sort=True) :
         """
-            Yield a series of nodes contained in this dir
+            Yield a series of Nodes contained in this dir.
+
+            If skip_dotfiles is given, nodes that begin with a . are omitted.
+
+            If `sort` is given, the returned nodes will be in sorted order.
         """
 
-        return (Node(self, fsname) for fsname in self.listdir(skip_dotfiles))
+        iter = (Node(self, fsname) for fsname in self.listdir(skip_dotfiles))
+
+        if sort :
+            return sorted(iter)
+
+        else :
+            return iter
 
     def __iter__ (self) :
         """
@@ -236,12 +299,14 @@
             Dotfiles are skipped.
         """
         
-        return self.childnodes()
+        return self.subnodes()
 
     @property
     def root_path (self) :
         """
             Build and return a relative path to the root of this dir tree
+
+            XXX: move to node
         """
         
         # build using parent root_path
@@ -256,6 +321,8 @@
 
             tuples, of which the first is a function that takes a Node as it's sole argument, and returns a boolean.
             For the first test_func which returns True, a Node-subclass object is constructed using node_type.from_node.
+
+            XXX: never used
         """
 
         for node in self :