degal/filesystem.py
author Tero Marttila <terom@fixme.fi>
Sun, 14 Jun 2009 16:19:27 +0300
changeset 109 66a01c0806f1
parent 97 92c20f8b297f
child 117 a2e4562deaab
permissions -rw-r--r--
backout config.read_only as a useless feature
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    Filesystem path handling
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
     5
import os, os.path, errno, stat
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
     6
import codecs, shutil
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
     7
import itertools
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
     8
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
     9
from utils import lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    11
class NodeError (Exception) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    12
    """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    13
        General exception class for errors associated with some specific node
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    14
    """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    15
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    16
    def __init__ (self, node, message) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    17
        super(NodeError, self).__init__(message)
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    18
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    19
        self.node = node
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    20
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    21
    def __str__ (self) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    22
        return "%s: %s" % (self.node, self.message)
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    23
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    24
    def __unicode__ (self) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    25
        return u"%s: %s" % (self.node, self.message)
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    26
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    27
    def __repr__ (self) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    28
        return "NodeError(%r, %r)" % (self.node, self.message)
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    29
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    30
class NodeErrno (NodeError) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    31
    """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    32
        OSError/errno errors for nodes
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    33
    """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    34
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    35
    def __init__ (self, node, errno) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    36
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    37
            Converts the given errno into an error message and uses that as the exception message
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    38
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    39
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    40
        super(NodeErrno, self).__init__(node, os.strerror(errno))
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    41
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
class Node (object) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
        A filesystem object is basically just complicated representation of a path.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
        On the plus side, it has a parent node and can handle unicode/binary paths.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    # the binary name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    fsname = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    # the unicode name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    name = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
    def decode_fsname (self, fsname) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
            Decode the given raw byte string representing a filesystem name into an user-readable unicode name.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
            XXX: currently just hardcoded as utf-8
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    60
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    61
            >>> Node(None, 'foo').decode_fsname('\xa5\xa6')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    62
            u'\\ufffd\\ufffd'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        return fsname.decode('utf-8', 'replace')
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
    def encode_name (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
            Returns a suitable fsname for the given unicode name or strict ASCII str
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
            XXX: currently just hardcoded as utf-8
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    72
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    73
            >>> Node(None, 'foo').encode_name(u'ab')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    74
            'ab'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
        # this should fail for non-ASCII str
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
        return name.encode('utf-8')
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    def __init__ (self, parent, fsname=None, name=None, config=None) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
            Initialize the node with a parent and both name/fsname.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
            If not given, fsname is encoded from name, or name decoded from fsname, using encode/decode_name.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    86
            If parent is given, but both fsname and name are None, then this node will be cloned from the parent.
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    87
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    88
            >>> Node(Root('/'), 'foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    89
            Node('/', 'foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    90
            >>> Node(Node(Root('/'), 'bar'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    91
            Node('/', 'bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    92
            >>> Node(None, fsname='foo\xa5').name
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    93
            u'foo\\ufffd'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    94
            >>> Node(None, name=u'foo').fsname
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    95
            'foo'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    97
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    98
        # fsname must not be an unicode string
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
        assert not fsname or isinstance(fsname, str)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
        if parent and not fsname and not name :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
            # no name given -> we're the same as parent
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
            self.parent, self.config, self.fsname, self.name = parent.parent, parent.config, parent.fsname, parent.name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
            # store
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
            self.parent = parent
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
            
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
            # config, either as given, or copy from parent
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
            if config :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
                self.config = config
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   112
            
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   113
            elif parent :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
                self.config = parent.config
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   115
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   116
            else :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   117
                # XXX: no config
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   118
                self.config = None
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
     
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
            # fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
            if fsname :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
                self.fsname = fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
            else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
                self.fsname = self.encode_name(name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
           
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
            # name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
            if name :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   129
                self.name = unicode(name)
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
            else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
                self.name = self.decode_fsname(fsname)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    def subnode (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
            Returns a Node object representing the given name behind this node.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
            The name should either be a plain ASCII string or unicode object.
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   139
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   140
            >>> Node(Root('/'), 'foo').subnode('bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   141
            Node('/foo', 'bar')
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
        return Node(self, name=name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
 
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   146
    def nodepath (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   147
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   148
            Returns the path of nodes from this node to the root node, inclusive
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   149
            >>> list(Node(Root('/'), 'foo').subnode('bar').nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   150
            [Root('/'), Node('/', 'foo'), Node('/foo', 'bar')]
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   151
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   152
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   153
        # recursive generator
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   154
        for node in self.parent.nodepath() :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   155
            yield node
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   156
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   157
        yield self
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   158
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   159
    @lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    def path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   162
            Return the machine-readable root-path for this node
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   163
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   164
            >>> Node(Root('/'), 'foo').subnode('bar').path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   165
            '/foo/bar'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   166
            >>> Node(Root('/'), name=u'foo').path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   167
            '/foo'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   168
            >>> Node(Root('/'), fsname='\\x01\\x02').path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   169
            '/\\x01\\x02'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
        # build using parent path and our fsname
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   173
        # XXX: rewrite using nodepath?
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
        return os.path.join(self.parent.path, self.fsname)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   176
    @lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
    def unicodepath (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   179
            Return the human-readable root-path for this node
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   180
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   181
            >>> Node(Root('/'), 'foo').subnode('bar').unicodepath
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   182
            u'/foo/bar'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   183
            >>> Node(Root('/'), name=u'foo').unicodepath
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   184
            u'/foo'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   185
            >>> Node(Root('/'), fsname='\\x01\\x02').unicodepath
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   186
            u'/??'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
        # build using parent unicodepath and our name
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   190
        # XXX: rewrte using nodepath?
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
        return os.path.join(self.parent.path, self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
   
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   193
    def path_segments (self, unicode=True) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   194
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   195
            Return a series of single-level names describing the path from the root to this node.
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   196
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   197
            If `unicode` is given, then the returned items will be the unicode names, otherwise, the binary names.
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   198
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   199
            >>> list(Node(Root('/'), 'foo').subnode('bar').path_segments())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   200
            [u'/', u'foo', u'bar']
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   201
            >>> list(Node(Root('/'), 'foo').subnode('bar').path_segments(unicode=False))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   202
            ['/', 'foo', 'bar']
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   203
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   204
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   205
        # iter
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   206
        for segment in self.parent.path_segments(unicode=unicode) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   207
            yield segment
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   208
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   209
        yield self.name if unicode else self.fsname
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   210
    
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   211
    @lazy_load
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   212
    def _stat (self) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   213
        """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   214
            Cached low-level stat.
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   215
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   216
            Returns None on ENOENT (node doesn't exist).
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   217
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   218
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   219
        try :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   220
            # syscall
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   221
            return os.stat(self.path)
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   222
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   223
        except OSError, e :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   224
            # trap ENOENT for soft
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   225
            if soft and e.errno == errno.ENOENT :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   226
                return None
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   227
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   228
            else :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   229
                raise
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   230
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   231
    def stat (self, soft=False) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   232
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   233
            Returns the os.stat struct for this node.
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   234
            
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   235
            If `soft` is given, returns None if this node doesn't exist.
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   236
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   237
            These stats are not cached.
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   238
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   239
            >>> Root('/').stat() is not None
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   240
            True
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   241
            >>> Root('/nonexistant').stat(soft=True) is None
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   242
            True
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   243
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   244
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   245
        if self._stat :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   246
            # got it
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   247
            return self._stat
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   248
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   249
        elif soft :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   250
            # doesn't exist
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   251
            return None
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   252
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   253
        else :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   254
            # not found
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   255
            raise NodeErrno(self, errno.ENOENT)
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   256
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
    def exists (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
            Tests if this node exists on the physical filesystem
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   260
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   261
            >>> Node(Root('.'), '.').exists()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   262
            True
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   263
            >>> Node(Root('/'), 'nonexistant').exists()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   264
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   267
        return self._stat is not None
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
    def is_dir (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
        """
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   271
            Tests if this node represents a directory on the physical filesystem.
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   272
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   273
            Returns False for non-existant files.
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   274
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   275
            >>> Node(Root('/'), '.').is_dir()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   276
            True
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   277
            >>> Root('/').subnode('dev').subnode('null').is_dir()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   278
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
        """
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   280
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   281
        return stat.S_ISDIR(self._stat.st_mode) if self._stat else False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
    def is_file (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   285
            Tests if this node represents a normal file on the physical filesystem
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   286
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   287
            Returns False for non-existant files.
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   288
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   289
            >>> Node(Root('/'), '.').is_file()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   290
            False
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   291
            >>> Root('/').subnode('dev').subnode('null').is_file()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   292
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   293
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   294
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   295
        return stat.S_ISREG(self._stat.st_mode) if self._stat else False
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   296
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   297
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   298
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   299
            Tests that this node exists. Raises an error it not, otherwise, returns the node itself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   300
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   301
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   302
        if not self.exists() :
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   303
            raise NodeErrno(self, errno.ENOENT)
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   304
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   305
        return self
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
    
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   307
    def path_to (self, node) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   308
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   309
            Returns a relative path from this node to the given node
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   310
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   311
            XXX: doctests
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   312
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   313
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   314
        # get real paths for both
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   315
        from_path = list(self.nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   316
        to_path = list(node.nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   317
        pivot = None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   318
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   319
        # reduce common prefix
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   320
        while from_path and to_path and from_path[0] == to_path[0] :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   321
            from_path.pop(0)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   322
            pivot = to_path.pop(0)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   323
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   324
        # full path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   325
        path = itertools.chain(reversed(from_path), [pivot] if pivot else (), to_path)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   326
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   327
        # build path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   328
        return Path(*path)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   329
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   330
    def path_from (self, node) :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   331
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   332
            Returns a relative path to this node from the given node.
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   333
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   334
            This is the same as path_to, but just reversed.
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   335
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   336
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   337
        return node.path_to(self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   338
    
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   339
    def __str__ (self) :
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   340
        return self.path
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   341
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   342
    def __unicode__ (self) :
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   343
        return self.unicodepath
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
    def __repr__ (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   346
        return "Node(%r, %r)" % (self.parent.path, self.fsname)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
    
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   348
    def __eq__ (self, other) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   349
        """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   350
            A Node is equal if compared to another node that shares the same name, and the parents are also equal.
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   351
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   352
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   353
        return isinstance(other, Node) and self.name == other.name and self.parent == other.parent
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   354
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   355
    def __cmp__ (self, other) :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   356
        """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   357
            Compare two Nodes or with None. This does not support comparisons with other kinds of objects.
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   358
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   359
            >>> cmp(Node(None, 'foo'), Node(None, 'foo'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   360
            0
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   361
            >>> cmp(Node(None, 'aaa'), Node(None, 'bbb'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   362
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   363
            >>> cmp(Node(None, 'bbb'), Node(None, 'aaa'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   364
            1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   365
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   366
            >>> cmp(Node(Node(None, 'a'), 'aa'), Node(Node(None, 'a'), 'aa'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   367
            0
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   368
            >>> cmp(Node(Node(None, 'a'), 'aa'), Node(Node(None, 'a'), 'ab'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   369
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   370
            >>> cmp(Node(Node(None, 'a'), 'ab'), Node(Node(None, 'a'), 'aa'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   371
            1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   372
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   373
            >>> cmp(Node(Node(None, 'a'), 'zz'), Node(Node(None, 'b'), 'aa'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   374
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   375
            >>> cmp(Node(Node(None, 'a'), 'aa'), Node(Node(None, 'b'), 'zz'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   376
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   377
            >>> cmp(Node(Node(None, 'z'), 'aa'), Node(Node(None, 'a'), 'zz'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   378
            1
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   379
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   380
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   381
        if other is None :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   382
            # arbitrary...
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   383
            return 1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   384
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   385
        else :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   386
            return cmp((self.parent, self.name), (other.parent if self.parent else None, other.name))
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   387
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   388
class Path (object) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   389
    """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   390
        A Path is a sequence of Nodes that form a path through a Node tree rooted at some Root.
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   391
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   392
        Each node must either be the parent or the child of the following node.
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   393
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   394
        The first and last nodes may be Files, but all other objects must be Directories.
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   395
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   396
        XXX: better to keep Paths symbolic/relative?
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   397
    """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   398
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   399
    def __init__ (self, *nodes) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   400
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   401
            Initialize with the given node path.
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   402
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   403
            The node path must not be empty.
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   404
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   405
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   406
        self.nodes = nodes
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   407
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   408
    def subpath (self, *nodes) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   409
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   410
            Returns a new path with the given node(s) appended
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   411
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   412
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   413
        return Path(*itertools.chain(self.nodes, nodes))
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   414
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   415
    def path_segments (self, unicode=True) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   416
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   417
            Yields a series of physical path segments for this path.
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   418
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   419
            File -> Directory : 
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   420
                file.parent == dir      -> nothing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   421
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   422
            Directory -> Directory :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   423
                dir_1.parent == dir_2   -> '..'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   424
                dir_1 == dir_2.parent   -> dir_2.name
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   425
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   426
            Directory -> File :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   427
                file.parent == dir      -> file.name
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   428
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   429
            >>> root = Root('root'); Path(root, root.subfile('foo'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   430
            Path('foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   431
            >>> root = Root('root'); Path(root, root.subdir('foo'), root.subdir('foo').subfile('bar'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   432
            Path('foo', 'bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   433
            >>> root = Root('root'); Path(root.subfile('foo'), root)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   434
            Path('.')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   435
            >>> root = Root('root'); Path(root.subfile('foo'), root, root.subfile('bar'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   436
            Path('bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   437
            >>> root = Root('root'); Path(root.subfile('foo'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   438
            Path('foo')
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   439
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   440
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   441
        # XXX: this logic should be implemented as methods in Node
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   442
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   443
        prev = prev_last = None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   444
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   445
        # output directory components
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   446
        for node in self.nodes :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   447
            if not prev :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   448
                # ignore the first item for now
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   449
                pass
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   450
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   451
            elif isinstance(prev, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   452
                # going from a file to its dir doesn't require anything
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   453
                assert isinstance(node, Directory) and prev.parent == node
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   454
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   455
            elif isinstance(node, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   456
                # final target, must come from a directory
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   457
                assert node is self.nodes[-1] and (not prev or (isinstance(prev, Directory) and node.parent == prev))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   458
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   459
            elif prev.parent == node :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   460
                # going from a dir into the dir above it
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   461
                yield '..'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   462
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   463
            elif node.parent == prev :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   464
                # going from a dir into a dir underneath it
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   465
                yield node.name if unicode else node.fsname
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   466
            
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   467
            else :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   468
                raise Exception("invalid path: %r" % (self.nodes, ))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   469
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   470
            # chained together
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   471
            prev_last = prev
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   472
            prev = node
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   473
            
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   474
        # output final file/lone dir component
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   475
        if isinstance(node, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   476
            # the last/only node is the final file target and must *always* be output
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   477
            yield node.name if unicode else node.fsname
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   478
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   479
        elif isinstance(node, Directory) and (prev_last is None or isinstance(prev_last, File)) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   480
            assert prev_last.parent == node
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   481
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   482
            # going from a file into it's own directory is a direct reference
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   483
            yield '.'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   484
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   485
    def __iter__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   486
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   487
            Iterate over the nodes
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   488
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   489
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   490
        return iter(self.nodes)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   491
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   492
    def __unicode__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   493
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   494
            Returns the unicode human-readable path
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   495
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   496
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   497
        return os.path.join(*self.path_segments(unicode=True))
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   498
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   499
    def __str__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   500
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   501
            Returns the binary machine-readable path
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   502
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   503
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   504
        return os.path.join(*self.path_segments(unicode=False))
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   505
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   506
    def __repr__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   507
        return "Path(%s)" % ', '.join(repr(segment) for segment in self.path_segments(unicode=False))
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   508
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   509
class File (Node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   510
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   511
        A file. Simple, eh?
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   512
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   513
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   514
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   515
    def basename (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   516
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   517
            Returns the "base" part of this file's name, i.e. the filename without the extension
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   518
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   519
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   520
        basename, _ = os.path.splitext(self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   521
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   522
        return basename
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   523
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   524
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   525
    def fileext (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   526
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   527
            Returns the file extension part of the file's name, without any leading dot
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   528
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   529
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   530
        _, fileext = os.path.splitext(self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   531
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   532
        # strip leading .
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   533
        return fileext[1:]
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   534
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   535
    def matchext (self, ext_list) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   536
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   537
            Tests if this file's extension is part of the recognized list of extensions
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   538
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   539
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   540
        return (self.fileext.lower() in ext_list)
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   541
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   542
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   543
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   544
            Tests that this file exists as a file. Raises an error it not, otherwise, returns itself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   545
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   546
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   547
        if not self.is_file() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   548
            raise Exception("File does not exist: %s" % self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   549
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   550
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   551
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   552
    def open (self, mode='r', encoding=None, errors=None, bufsize=None) :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   553
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   554
            Wrapper for open/codecs.open.
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   555
        """
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   556
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   557
        if encoding :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   558
            return codecs.open(self.path, mode, encoding, errors, bufsize)
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   559
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   560
        else :
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   561
            return open(self.path, mode, *(arg for arg in (bufsize, ) if arg is not None))
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   562
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   563
    def open_write (self, *args, **kwargs) :
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   564
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   565
            Open for write using open('w').
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   566
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   567
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   568
        return self.open('w', *args, **kwargs)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   569
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   570
    def copy_from (self, file) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   571
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   572
            Replace this file with a copy of the given file with default permissions.
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   573
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   574
            XXX: accept mode
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   575
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   576
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   577
        # perform the copy
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   578
        shutil.copyfile(file.path, self.path)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   579
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   580
    def newer_than (self, file) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   581
        """
93
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   582
            Returns True if both files exist, and this file is newer than the given file.
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   583
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   584
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   585
        if self._stat and file._stat :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   586
            return self._stat.st_mtime > file._stat.st_mtime
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   587
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   588
        else :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   589
            return None
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   590
    
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   591
    def older_than (self, file) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   592
        """
93
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   593
            Returns True if both files exist, and this file is older than the given file.
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   594
        """
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   595
        
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   596
        # mirror
95
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 93
diff changeset
   597
        return file.newer_than(self)
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   598
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   599
class Directory (Node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   600
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   601
        A directory is a node that contains other nodes.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   602
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   603
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   604
    # a list of (test_func, node_type) tuples for use by children() to build subnodes with
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   605
    NODE_TYPES = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   606
   
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   607
    def subdir (self, name, create=False) :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   608
        """
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   609
            Returns a Directory object representing the name underneath this dir.
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   610
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   611
            If the create option is given, the directory will be created if it does not exist.
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   612
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   613
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   614
        subdir = Directory(self, name=name)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   615
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   616
        if create and not subdir.is_dir() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   617
            # create it!
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   618
            subdir.mkdir()
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   619
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   620
        return subdir
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   621
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   622
    def subfile (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   623
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   624
            Returns a File object representing the name underneath this dir
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   625
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   626
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   627
        return File(self, name=name)
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   628
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   629
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   630
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   631
            Tests that this dir exists as a dir. Raises an error it not, otherwise, returns itself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   632
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   633
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   634
        if not self.is_dir() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   635
            raise Exception("Directory does not exist: %s" % self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   636
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   637
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   638
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   639
    def mkdir (self) :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   640
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   641
            Create this directory with default permissions.
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   642
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   643
            XXX: mode argument
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   644
        """
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   645
        
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   646
        # do it
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   647
        os.mkdir(self.path)
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   648
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   649
    def listdir (self, skip_dotfiles=True) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   650
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   651
            Yield a series of raw fsnames for nodes in this dir
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   652
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   653
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   654
        # expressed 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   655
        return (fsname for fsname in os.listdir(self.path) if not (skip_dotfiles and fsname.startswith('.')))
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   656
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   657
    def subnodes (self, skip_dotfiles=True, sort=True) :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   658
        """
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   659
            Yield a series of Nodes contained in this dir.
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   660
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   661
            If skip_dotfiles is given, nodes that begin with a . are omitted.
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   662
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   663
            If `sort` is given, the returned nodes will be in sorted order.
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   664
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   665
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   666
        iter = (Node(self, fsname) for fsname in self.listdir(skip_dotfiles))
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   667
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   668
        if sort :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   669
            return sorted(iter)
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   670
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   671
        else :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   672
            return iter
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   673
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   674
    __iter__ = subnodes
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   675
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   676
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   677
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   678
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   679
            Build and return a relative path to the root of this dir tree
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   680
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   681
            XXX: move to node
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   682
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   683
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   684
        # build using parent root_path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   685
        return os.path.join('..', self.parent.root_path)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   686
 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   687
class Root (Directory) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   688
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   689
        A special Directory that overrides the Node methods to anchor the recursion/etc at some 'real' filesystem path.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   690
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   691
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   692
    # XXX: config needs a default
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   693
    def __init__ (self, fspath, config=None) :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   694
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   695
            Construct the directory tree root at the given 'real' path, which must be a raw str
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   696
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   697
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   698
        # abuse Node's concept of a "name" a bit
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   699
        super(Root, self).__init__(None, fspath)
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   700
        
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   701
        # store our config
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   702
        self.config = config
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   703
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   704
    def nodepath (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   705
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   706
            Just return ourself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   707
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   708
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   709
        return [self]
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   710
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   711
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   712
    def path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   713
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   714
            Returns the raw path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   715
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   716
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   717
        return self.fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   718
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   719
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   720
    def unicodepath (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   721
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   722
            Returns the raw decoded path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   723
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   724
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   725
        return self.name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   726
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   727
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   728
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   729
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   730
            Returns an empty string representing this dir
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   731
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   732
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   733
        return ''
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   734
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   735
    def path_segments (self, unicode=True) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   736
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   737
            No path segments other than our own
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   738
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   739
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   740
        yield self.name if unicode else self.fsname
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   741
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   742
    def __repr__ (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   743
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   744
            Override Node.__repr__ to not use self.parent.path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   745
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   746
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   747
        return "Root(%r)" % self.fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   748
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   749
# testing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   750
if __name__ == '__main__' :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   751
    import doctest
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   752
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   753
    doctest.testmod()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   754