degal/filesystem.py
author Tero Marttila <terom@fixme.fi>
Sun, 14 Jun 2009 20:05:11 +0300
changeset 117 a2e4562deaab
parent 109 66a01c0806f1
child 118 60b126ff0b74
permissions -rw-r--r--
implement concurrency... :)
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
117
a2e4562deaab implement concurrency... :)
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   149
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   150
            >>> 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
   151
            [Root('/'), Node('/', 'foo'), Node('/foo', 'bar')]
117
a2e4562deaab implement concurrency... :)
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   152
a2e4562deaab implement concurrency... :)
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   153
            XXX: circular reference hell?
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   154
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   155
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   156
        # recursive generator
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   157
        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
   158
            yield node
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   159
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   160
        yield self
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   161
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   162
    @lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    def path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   165
            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
   166
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   167
            >>> 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
   168
            '/foo/bar'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   169
            >>> 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
   170
            '/foo'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   171
            >>> 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
   172
            '/\\x01\\x02'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        # 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
   176
        # XXX: rewrite using nodepath?
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        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
   178
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   179
    @lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    def unicodepath (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   182
            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
   183
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   184
            >>> 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
   185
            u'/foo/bar'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   186
            >>> 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
   187
            u'/foo'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   188
            >>> 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
   189
            u'/??'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        # 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
   193
        # XXX: rewrte using nodepath?
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
        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
   195
   
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   196
    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
   197
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   198
            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
   199
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   200
            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
   201
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   202
            >>> 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
   203
            [u'/', u'foo', u'bar']
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   204
            >>> 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
   205
            ['/', 'foo', 'bar']
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   206
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   207
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   208
        # iter
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   209
        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
   210
            yield segment
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   211
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   212
        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
   213
    
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   214
    @lazy_load
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   215
    def _stat (self) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   216
        """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   217
            Cached low-level stat.
97
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
            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
   220
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   221
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   222
        try :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   223
            # syscall
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   224
            return os.stat(self.path)
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   225
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   226
        except OSError, e :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   227
            # trap ENOENT for soft
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   228
            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
   229
                return None
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
            else :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   232
                raise
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   233
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   234
    def stat (self, soft=False) :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   235
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   236
            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
   237
            
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   238
            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
   239
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   240
            These stats are not cached.
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   241
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   242
            >>> Root('/').stat() is not None
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   243
            True
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   244
            >>> 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
   245
            True
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   246
        """
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   247
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   248
        if self._stat :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   249
            # got it
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   250
            return self._stat
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   251
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   252
        elif soft :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   253
            # doesn't exist
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   254
            return None
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   255
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   256
        else :
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   257
            # not found
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   258
            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
   259
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
    def exists (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
            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
   263
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   264
            >>> Node(Root('.'), '.').exists()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   265
            True
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   266
            >>> Node(Root('/'), 'nonexistant').exists()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   267
            False
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
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   270
        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
   271
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
    def is_dir (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
        """
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   274
            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
   275
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   276
            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
   277
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   278
            >>> Node(Root('/'), '.').is_dir()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   279
            True
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   280
            >>> 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
   281
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
        """
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   283
        
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   284
        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
   285
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
    def is_file (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   288
            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
   289
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   290
            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
   291
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   292
            >>> Node(Root('/'), '.').is_file()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   293
            False
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   294
            >>> 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
   295
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   298
        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
   299
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   300
    def test (self) :
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
            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
   303
        """
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
        if not self.exists() :
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   306
            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
   307
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   308
        return self
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
    
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   310
    def path_to (self, node) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   311
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   312
            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
   313
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   314
            XXX: doctests
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   315
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   316
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   317
        # get real paths for both
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   318
        from_path = list(self.nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   319
        to_path = list(node.nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   320
        pivot = None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   321
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   322
        # reduce common prefix
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   323
        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
   324
            from_path.pop(0)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   325
            pivot = to_path.pop(0)
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
        # full path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   328
        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
   329
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   330
        # build path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   331
        return Path(*path)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   332
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
   333
    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
   334
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   335
            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
   336
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   337
            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
   338
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   339
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   340
        return node.path_to(self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   341
    
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   342
    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
   343
        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
   344
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   345
    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
   346
        return self.unicodepath
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   348
    def __repr__ (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   349
        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
   350
    
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   351
    def __eq__ (self, other) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   352
        """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   353
            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
   354
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   355
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   356
        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
   357
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   358
    def __cmp__ (self, other) :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   359
        """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   360
            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
   361
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   362
            >>> 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
   363
            0
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   364
            >>> 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
   365
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   366
            >>> 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
   367
            1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   368
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   369
            >>> 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
   370
            0
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   371
            >>> 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
   372
            -1
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'), '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
   374
            1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   375
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   376
            >>> 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
   377
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   378
            >>> 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
   379
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   380
            >>> 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
   381
            1
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   382
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   383
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   384
        if other is None :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   385
            # arbitrary...
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   386
            return 1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   387
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   388
        else :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   389
            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
   390
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   391
class Path (object) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   392
    """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   393
        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
   394
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   395
        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
   396
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   397
        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
   398
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   399
        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
   400
    """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   401
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   402
    def __init__ (self, *nodes) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   403
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   404
            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
   405
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   406
            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
   407
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   408
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   409
        self.nodes = nodes
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   410
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   411
    def subpath (self, *nodes) :
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
            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
   414
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   415
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   416
        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
   417
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   418
    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
   419
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   420
            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
   421
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   422
            File -> Directory : 
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   423
                file.parent == dir      -> nothing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   424
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   425
            Directory -> Directory :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   426
                dir_1.parent == dir_2   -> '..'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   427
                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
   428
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   429
            Directory -> File :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   430
                file.parent == dir      -> file.name
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   431
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   432
            >>> 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
   433
            Path('foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   434
            >>> 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
   435
            Path('foo', 'bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   436
            >>> 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
   437
            Path('.')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   438
            >>> 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
   439
            Path('bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   440
            >>> 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
   441
            Path('foo')
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   442
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   443
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   444
        # 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
   445
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   446
        prev = prev_last = None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   447
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   448
        # output directory components
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   449
        for node in self.nodes :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   450
            if not prev :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   451
                # 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
   452
                pass
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   453
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   454
            elif isinstance(prev, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   455
                # 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
   456
                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
   457
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   458
            elif isinstance(node, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   459
                # 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
   460
                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
   461
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   462
            elif prev.parent == node :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   463
                # 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
   464
                yield '..'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   465
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   466
            elif node.parent == prev :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   467
                # 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
   468
                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
   469
            
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   470
            else :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   471
                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
   472
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   473
            # chained together
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   474
            prev_last = prev
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   475
            prev = node
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   476
            
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   477
        # 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
   478
        if isinstance(node, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   479
            # 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
   480
            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
   481
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   482
        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
   483
            assert prev_last.parent == node
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   484
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   485
            # 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
   486
            yield '.'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   487
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   488
    def __iter__ (self) :
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
            Iterate over the 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
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   493
        return iter(self.nodes)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   494
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   495
    def __unicode__ (self) :
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
            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
   498
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   499
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   500
        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
   501
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   502
    def __str__ (self) :
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
            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
   505
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   506
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   507
        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
   508
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   509
    def __repr__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   510
        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
   511
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   512
class File (Node) :
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
        A file. Simple, eh?
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   515
    """
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
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   518
    def basename (self) :
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
            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
   521
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   522
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   523
        basename, _ = os.path.splitext(self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   524
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   525
        return basename
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
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   528
    def fileext (self) :
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
            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
   531
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   532
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   533
        _, fileext = os.path.splitext(self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   534
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   535
        # strip leading .
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   536
        return fileext[1:]
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   537
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   538
    def matchext (self, ext_list) :
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
            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
   541
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   542
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   543
        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
   544
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   545
    def test (self) :
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
            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
   548
        """
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
        if not self.is_file() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   551
            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
   552
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   553
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   554
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
    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
   556
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   557
            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
   558
        """
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
        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
   561
            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
   562
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   563
        else :
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   564
            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
   565
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   566
    def open_write (self, *args, **kwargs) :
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   567
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   568
            Open for write using open('w').
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   569
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   570
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   571
        return self.open('w', *args, **kwargs)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   572
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   573
    def copy_from (self, file) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   574
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   575
            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
   576
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   577
            XXX: accept mode
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   578
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   579
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   580
        # perform the copy
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   581
        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
   582
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
    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
   584
        """
93
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   585
            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
   586
        """
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
97
92c20f8b297f implement simple stat caching using lazy_load for filesystem
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   588
        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
   589
            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
   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
        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
   592
            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
   593
    
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
   594
    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
   595
        """
93
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   596
            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
   597
        """
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   598
        
d3872a673fbe fix File.newer_than/File.older_than to correctly handle None
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   599
        # mirror
95
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 93
diff changeset
   600
        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
   601
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   602
class Directory (Node) :
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 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
   605
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   606
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   607
    # 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
   608
    NODE_TYPES = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   609
   
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
   610
    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
   611
        """
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
   612
            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
   613
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   614
            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
   615
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   616
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   617
        subdir = Directory(self, name=name)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   618
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   619
        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
   620
            # create it!
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   621
            subdir.mkdir()
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   622
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   623
        return subdir
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   624
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   625
    def subfile (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   626
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   627
            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
   628
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   629
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   630
        return File(self, name=name)
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   631
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   632
    def test (self) :
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
            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
   635
        """
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
        if not self.is_dir() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   638
            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
   639
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   640
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   641
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
   642
    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
   643
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   644
            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
   645
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
   646
            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
   647
        """
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
        
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   649
        # 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
   650
        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
   651
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   652
    def listdir (self, skip_dotfiles=True) :
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
            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
   655
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   656
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   657
        # expressed 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   658
        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
   659
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
   660
    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
   661
        """
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
   662
            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
   663
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   664
            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
   665
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
            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
   667
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   668
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
   669
        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
   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
        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
   672
            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
   673
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   674
        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
   675
            return iter
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   676
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   677
    __iter__ = subnodes
51
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
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   680
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   681
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   682
            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
   683
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   684
            XXX: move to node
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   685
        """
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
        # build using parent root_path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   688
        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
   689
 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   690
class Root (Directory) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   691
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   692
        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
   693
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   694
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   695
    # XXX: config needs a default
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   696
    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
   697
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   698
            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
   699
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   700
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   701
        # abuse Node's concept of a "name" a bit
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   702
        super(Root, self).__init__(None, fspath)
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   703
        
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   704
        # store our config
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   705
        self.config = config
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   706
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   707
    def nodepath (self) :
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
            Just return ourself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   710
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   711
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   712
        return [self]
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   713
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   714
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   715
    def path (self) :
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
            Returns the raw path
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
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   720
        return self.fsname
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
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   723
    def unicodepath (self) :
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
            Returns the raw decoded path
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
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   728
        return self.name
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
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   731
    def root_path (self) :
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
            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
   734
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   735
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   736
        return ''
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   737
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   738
    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
   739
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   740
            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
   741
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   742
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   743
        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
   744
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   745
    def __repr__ (self) :
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
            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
   748
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   749
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   750
        return "Root(%r)" % self.fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   751
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   752
# testing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   753
if __name__ == '__main__' :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   754
    import doctest
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   755
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   756
    doctest.testmod()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   757