degal/filesystem.py
author Tero Marttila <terom@fixme.fi>
Wed, 10 Jun 2009 23:33:28 +0300
changeset 84 891545a38a2b
parent 79 e5400304a3d3
child 85 7da934333469
permissions -rw-r--r--
change utils.LazyProperty to store the cached value using obj.__dict__
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
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
     5
import os, os.path, errno
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
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
class Node (object) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
        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
    14
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
        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
    16
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
    # the binary name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
    fsname = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
    # the unicode name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
    name = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    def decode_fsname (self, fsname) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
            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
    27
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
            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
    29
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    30
            >>> 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
    31
            u'\\ufffd\\ufffd'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
        return fsname.decode('utf-8', 'replace')
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    def encode_name (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
            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
    39
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
            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
    41
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    42
            >>> 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
    43
            'ab'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
        """
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
        # 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
    47
        return name.encode('utf-8')
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
    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
    50
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
            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
    52
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
            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
    54
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    55
            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
    56
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    57
            >>> Node(Root('/'), 'foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    58
            Node('/', 'foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    59
            >>> Node(Node(Root('/'), 'bar'))
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    60
            Node('/', 'bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    61
            >>> 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
    62
            u'foo\\ufffd'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    63
            >>> 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
    64
            'foo'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    66
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    67
        # 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
    68
        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
    69
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
        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
    71
            # 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
    72
            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
    73
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
        else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
            # store
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
            self.parent = parent
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
            
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
            # 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
    79
            if config :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
                self.config = config
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
    81
            
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    82
            elif parent :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
                self.config = parent.config
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    84
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    85
            else :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    86
                # XXX: no config
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    87
                self.config = None
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
     
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
            # fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
            if fsname :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
                self.fsname = fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
            else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
                self.fsname = self.encode_name(name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
           
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
            # name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
            if name :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    98
                self.name = unicode(name)
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
            else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
                self.name = self.decode_fsname(fsname)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    def subnode (self, 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
            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
   106
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
            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
   108
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   109
            >>> Node(Root('/'), 'foo').subnode('bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   110
            Node('/foo', 'bar')
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
        return Node(self, name=name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
 
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   115
    def nodepath (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   116
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   117
            Returns the path of nodes from this node to the root node, inclusive
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   118
            >>> 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
   119
            [Root('/'), Node('/', 'foo'), Node('/foo', 'bar')]
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   120
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   121
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   122
        # recursive generator
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   123
        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
   124
            yield node
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   125
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   126
        yield self
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   127
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   128
    @lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
    def path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   131
            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
   132
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   133
            >>> 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
   134
            '/foo/bar'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   135
            >>> 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
   136
            '/foo'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   137
            >>> 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
   138
            '/\\x01\\x02'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
        # 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
   142
        # XXX: rewrite using nodepath?
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
        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
   144
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   145
    @lazy_load
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
    def unicodepath (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   148
            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
   149
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   150
            >>> 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
   151
            u'/foo/bar'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   152
            >>> 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
   153
            u'/foo'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   154
            >>> 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
   155
            u'/??'
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
        # 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
   159
        # XXX: rewrte using nodepath?
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
        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
   161
   
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   162
    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
   163
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   164
            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
   165
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   166
            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
   167
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   168
            >>> 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
   169
            [u'/', u'foo', u'bar']
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   170
            >>> 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
   171
            ['/', 'foo', 'bar']
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   172
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   173
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   174
        # iter
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   175
        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
   176
            yield segment
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   177
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   178
        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
   179
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    def exists (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
            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
   183
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   184
            >>> Node(Root('.'), '.').exists()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   185
            True
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   186
            >>> Node(Root('/'), 'nonexistant').exists()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   187
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        return os.path.exists(self.path)
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
    def is_dir (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   194
            Tests if this node represents a directory on the physical filesystem
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   195
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   196
            >>> Node(Root('/'), '.').is_dir()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   197
            True
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   198
            >>> 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
   199
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
        return os.path.isdir(self.path)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
    def is_file (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   206
            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
   207
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   208
            >>> Node(Root('/'), '.').is_file()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   209
            False
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   210
            >>> 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
   211
            False
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
        return os.path.isfile(self.path)
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   215
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   216
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   217
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   218
            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
   219
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   220
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   221
        if not self.exists() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   222
            raise Exception("Filesystem node does not exist: %s" % self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   223
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   224
        return self
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
    
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   226
    def path_to (self, node) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   227
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   228
            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
   229
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   230
            XXX: doctests
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   231
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   232
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   233
        # get real paths for both
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   234
        from_path = list(self.nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   235
        to_path = list(node.nodepath())
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   236
        pivot = None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   237
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   238
        # reduce common prefix
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   239
        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
   240
            from_path.pop(0)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   241
            pivot = to_path.pop(0)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   242
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   243
        # full path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   244
        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
   245
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   246
        # build path
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   247
        return Path(*path)
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   248
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
   249
    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
   250
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   251
            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
   252
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   253
            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
   254
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   255
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   256
        return node.path_to(self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   257
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
   258
    def stat (self, soft=False) :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   259
        """
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   260
            Returns the os.stat struct for this 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
   261
            
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   262
            If `soft` is given, returns None if this node doesn't exist
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
            >>> Root('/').stat() is not None
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
            >>> Root('/nonexistant').stat(soft=True) is None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   267
            True
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
   268
        """
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   269
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   270
        try :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   271
            return os.stat(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
   272
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   273
        except OSError, e :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   274
            # trap ENOENT for soft
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   275
            if soft and e.errno == errno.ENOENT :
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   276
                return 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
   277
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   278
            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
   279
                raise
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   280
    
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   281
    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
   282
        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
   283
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   284
    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
   285
        return self.unicodepath
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
    def __repr__ (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
            Returns a str representing this dir
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   292
        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
   293
    
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   294
    def __eq__ (self, other) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   295
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   296
            Compare for equality
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   297
        """
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   298
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   299
        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
   300
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   301
    def __cmp__ (self, other) :
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   303
            Arbitrary comparisons between Nodes
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   304
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   305
            >>> 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
   306
            0
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   307
            >>> 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
   308
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   309
            >>> 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
   310
            1
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
            >>> 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
   313
            0
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   314
            >>> 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
   315
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   316
            >>> 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
   317
            1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   318
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   319
            >>> 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
   320
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   321
            >>> 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
   322
            -1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   323
            >>> 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
   324
            1
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   327
        if other is None :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   328
            # arbitrary...
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   329
            return 1
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   330
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   331
        else :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   332
            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
   333
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   334
class Path (object) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   335
    """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   336
        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
   337
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   338
        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
   339
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   340
        The first and last nodes may be Files, but all other objects must be Directories.
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   341
    """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   342
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   343
    def __init__ (self, *nodes) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   344
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   345
            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
   346
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   347
            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
   348
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   349
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   350
        self.nodes = nodes
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   351
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   352
    def subpath (self, *nodes) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   353
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   354
            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
   355
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   356
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   357
        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
   358
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   359
    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
   360
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   361
            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
   362
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   363
            File -> Directory : 
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   364
                file.parent == dir      -> nothing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   365
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   366
            Directory -> Directory :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   367
                dir_1.parent == dir_2   -> '..'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   368
                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
   369
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   370
            Directory -> File :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   371
                file.parent == dir      -> file.name
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   372
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   373
            >>> 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
   374
            Path('foo')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   375
            >>> 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
   376
            Path('foo', 'bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   377
            >>> 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
   378
            Path('.')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   379
            >>> 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
   380
            Path('bar')
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   381
            >>> 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
   382
            Path('foo')
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   383
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   384
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   385
        # 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
   386
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   387
        prev = prev_last = None
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   388
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   389
        # output directory components
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   390
        for node in self.nodes :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   391
            if not prev :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   392
                # 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
   393
                pass
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   394
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   395
            elif isinstance(prev, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   396
                # 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
   397
                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
   398
            
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   399
            elif isinstance(node, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   400
                # 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
   401
                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
   402
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   403
            elif prev.parent == node :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   404
                # 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
   405
                yield '..'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   406
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   407
            elif node.parent == prev :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   408
                # 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
   409
                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
   410
            
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   411
            else :
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   412
                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
   413
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   414
            # chained together
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   415
            prev_last = prev
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   416
            prev = node
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   417
            
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   418
        # 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
   419
        if isinstance(node, File) :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   420
            # 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
   421
            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
   422
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   423
        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
   424
            assert prev_last.parent == node
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   425
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   426
            # 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
   427
            yield '.'
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   428
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   429
    def __iter__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   430
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   431
            Iterate over the nodes
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   432
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   433
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   434
        return iter(self.nodes)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   435
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   436
    def __unicode__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   437
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   438
            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
   439
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   440
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   441
        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
   442
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   443
    def __str__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   444
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   445
            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
   446
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   447
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   448
        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
   449
    
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   450
    def __repr__ (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   451
        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
   452
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   453
class File (Node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   454
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   455
        A file. Simple, eh?
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   456
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   457
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   458
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   459
    def basename (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   460
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   461
            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
   462
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   463
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   464
        basename, _ = os.path.splitext(self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   465
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   466
        return basename
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   467
    
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   468
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   469
    def fileext (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   470
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   471
            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
   472
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   473
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   474
        _, fileext = os.path.splitext(self.name)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   475
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   476
        # strip leading .
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   477
        return fileext[1:]
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   478
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   479
    def matchext (self, ext_list) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   480
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   481
            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
   482
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   483
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   484
        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
   485
    
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   486
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   487
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   488
            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
   489
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   490
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   491
        if not self.is_file() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   492
            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
   493
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   494
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   495
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
   496
    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
   497
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   498
            Wrapper for open/codecs.open.
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
            Raises an error if read_only mode is set and mode contains any of 'wa+'
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
   501
        """
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   502
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   503
        if self.config.read_only and any((c in mode) for c in 'wa+') :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   504
            raise Exception("Unable to open file for %s due to read_only mode: %s" % (mode, self))
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   505
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
   506
        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
   507
            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
   508
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   509
        else :
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   510
            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
   511
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   512
    def open_write (self, *args, **kwargs) :
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   513
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   514
            Open for write using open('w').
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   515
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   516
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   517
        return self.open('w', *args, **kwargs)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   518
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   519
    def copy_from (self, file) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   520
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   521
            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
   522
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   523
            Raises an error if read_only mode is set.
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   524
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   525
            XXX: accept mode
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   526
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   527
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   528
        if self.config.read_only :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   529
            raise Exception("Not copying file as read_only mode is set: %s -> %s" % (file, self))
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   530
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   531
        # perform the copy
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   532
        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
   533
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   534
class Directory (Node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   535
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   536
        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
   537
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   538
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   539
    # 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
   540
    NODE_TYPES = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   541
   
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
   542
    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
   543
        """
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
            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
   545
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   546
            If the create option is given, the directory will be created if it does not exist. Note that this will
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   547
            raise an error if read_only mode is set
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   548
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   549
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   550
        subdir = Directory(self, name=name)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   551
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   552
        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
   553
            # create it!
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   554
            subdir.mkdir()
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   555
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   556
        return subdir
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   557
    
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   558
    def test_subdir (self, name, create=False) :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   559
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   560
            Test for the presence of a subdir with the given name, and possibly return it, or None.
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   561
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   562
            Returns a (exists, created, dir) tuple.
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   563
            
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   564
            XXX: ugly, not used
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   565
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   566
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   567
        subdir = Directory(self, name=name)
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   568
        
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   569
        # already exists?
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   570
        if subdir.is_dir() :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   571
            if create :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   572
                # create it!
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   573
                subdir.mkdir()
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   574
                
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   575
                # didn't exist, did create
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   576
                return True, True, subdir
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   577
            
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   578
            else :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   579
                # doesn't exist, don't create
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   580
                return False, False, subdir
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   581
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   582
        else :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   583
            # already existing
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   584
            return True, False, subdir
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   585
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   586
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   587
    def subfile (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   588
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   589
            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
   590
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   591
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   592
        return File(self, name=name)
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   593
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   594
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   595
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   596
            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
   597
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   598
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   599
        if not self.is_dir() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   600
            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
   601
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   602
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   603
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
   604
    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
   605
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   606
            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
   607
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   608
            This will fail if read_only mode is set
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   609
            
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
            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
   611
        """
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
        
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   613
        if self.config.read_only :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   614
            # forbidden
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   615
            raise Exception("Unable to create dir due to read_only mode: %s" % self)
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   616
        
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
   617
        # 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
   618
        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
   619
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   620
    def listdir (self, skip_dotfiles=True) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   621
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   622
            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
   623
        """
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
        # expressed 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   626
        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
   627
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
   628
    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
   629
        """
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
   630
            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
   631
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   632
            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
   633
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   634
            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
   635
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   636
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
   637
        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
   638
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   639
        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
   640
            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
   641
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
        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
   643
            return iter
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   644
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   645
    __iter__ = subnodes
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   646
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   647
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   648
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   649
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   650
            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
   651
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   652
            XXX: move to node
51
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
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   655
        # build using parent root_path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   656
        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
   657
 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   658
    def children (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   659
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   660
            Yield a series of Node subclasses representing the items in this dir.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   661
            
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   662
            This uses self.NODE_TYPES to figure out what kind of sub-node object to build. This should be a list of
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   663
                (test_func, node_type)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   664
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   665
            tuples, of which the first is a function that takes a Node as it's sole argument, and returns a boolean.
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   666
            For the first test_func which returns True, a Node-subclass object is constructed using node_type.from_node.
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
   667
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   668
            XXX: never used
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   669
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   670
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   671
        for node in self :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   672
            # figure out what type to use
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   673
            for test_func, node_type in self.NODE_TYPES :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   674
                if test_func(node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   675
                    # matches, build
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   676
                    yield node_type.from_node(node)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   677
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   678
            else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   679
                # unknown file type!
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   680
                raise Exception("unrecongized type of file: %s" % node);
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
# assign default Directory.NODE_TYPES
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   683
Directory.NODE_TYPES = [
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   684
    (Node.is_dir,   Directory),
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   685
    (Node.is_file,  File),
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
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   688
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   689
class Root (Directory) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   690
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   691
        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
   692
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   693
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   694
    # XXX: config needs a default
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   695
    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
   696
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   697
            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
   698
        """
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
        # abuse Node's concept of a "name" a bit
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   701
        super(Root, self).__init__(None, fspath)
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   702
        
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   703
        # store our config
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   704
        self.config = config
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   705
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   706
    def nodepath (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   707
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   708
            Just return ourself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   709
        """
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
        return [self]
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   712
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   713
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   714
    def path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   715
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   716
            Returns the raw path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   717
        """
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
        return self.fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   720
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   721
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   722
    def unicodepath (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   723
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   724
            Returns the raw decoded path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   725
        """
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
        return self.name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   728
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   729
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   730
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   731
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   732
            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
   733
        """
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
        return ''
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   736
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   737
    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
   738
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   739
            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
   740
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   741
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   742
        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
   743
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   744
    def __repr__ (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   745
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   746
            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
   747
        """
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
        return "Root(%r)" % self.fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   750
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   751
# testing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   752
if __name__ == '__main__' :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   753
    import doctest
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   754
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   755
    doctest.testmod()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   756