# HG changeset patch # User Tero Marttila # Date 1244219291 -10800 # Node ID 77abe8dca695f2f09c28839254511d510e7ef30a # Parent cc007b6ab972a1b8afbb7b3ee7c1a687739eb29f further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes diff -r cc007b6ab972 -r 77abe8dca695 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 :