degal/filesystem.py
author Tero Marttila <terom@fixme.fi>
Thu, 11 Jun 2009 00:36:19 +0300
changeset 85 7da934333469
parent 79 e5400304a3d3
child 93 d3872a673fbe
permissions -rw-r--r--
move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
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
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   534
    def newer_than (self, file) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   535
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   536
            Tests if this file is newer than the given file.
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   537
            
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   538
            Returns True if it is, False if it isn't, or None if either file doesn't exist.
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   539
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   540
            XXX: stat cache?
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   541
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   542
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   543
        stat_self = self.stat(soft=True)
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   544
        stat_file = file.stat(soft=True)
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   545
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   546
        if stat_self and stat_file :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   547
            return stat_self.st_mtime > stat_file.st_mtime
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   548
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   549
        else :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   550
            return None
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   551
    
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   552
    def older_than (self, file) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   553
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   554
            Tests if this file is older than the given file.
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   555
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   556
            Opposite of newer_than.
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   557
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   558
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   559
        return file.newer_than(self)
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents: 79
diff changeset
   560
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   561
class Directory (Node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   562
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   563
        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
   564
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   565
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   566
    # 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
   567
    NODE_TYPES = None
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   568
   
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
   569
    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
   570
        """
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
   571
            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
   572
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   573
            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
   574
            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
   575
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   576
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   577
        subdir = Directory(self, name=name)
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   578
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   579
        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
   580
            # create it!
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   581
            subdir.mkdir()
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   582
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   583
        return subdir
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   584
    
68
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   585
    def test_subdir (self, name, create=False) :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   586
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   587
            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
   588
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   589
            Returns a (exists, created, dir) tuple.
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   590
            
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   591
            XXX: ugly, not used
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   592
        """
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   593
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   594
        subdir = Directory(self, name=name)
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   595
        
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   596
        # already exists?
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   597
        if subdir.is_dir() :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   598
            if create :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   599
                # create it!
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   600
                subdir.mkdir()
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   601
                
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   602
                # didn't exist, did create
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   603
                return True, True, subdir
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   604
            
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   605
            else :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   606
                # doesn't exist, don't create
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   607
                return False, False, subdir
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   608
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   609
        else :
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   610
            # already existing
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   611
            return True, False, subdir
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   612
49388e9fd5fa add open_write method for filesystem.File
Tero Marttila <terom@fixme.fi>
parents: 60
diff changeset
   613
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   614
    def subfile (self, name) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   615
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   616
            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
   617
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   618
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
   619
        return File(self, name=name)
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   620
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   621
    def test (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   622
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   623
            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
   624
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   625
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   626
        if not self.is_dir() :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   627
            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
   628
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   629
        return self
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   630
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
   631
    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
   632
        """
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   633
            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
   634
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   635
            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
   636
            
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
            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
   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
        
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   640
        if self.config.read_only :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   641
            # forbidden
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   642
            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
   643
        
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
   644
        # 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
   645
        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
   646
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   647
    def listdir (self, skip_dotfiles=True) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   648
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   649
            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
   650
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   651
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   652
        # expressed 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   653
        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
   654
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
   655
    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
   656
        """
55
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   657
            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
   658
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   659
            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
   660
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   661
            If `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
   662
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   663
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
   664
        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
   665
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   666
        if sort :
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
            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
   668
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   669
        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
   670
            return iter
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   671
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   672
    __iter__ = subnodes
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   673
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   674
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   675
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   676
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   677
            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
   678
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   679
            XXX: move to node
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   680
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   681
        
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   682
        # build using parent root_path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   683
        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
   684
 
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   685
    def children (self) :
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
            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
   688
            
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   689
            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
   690
                (test_func, node_type)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   691
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   692
            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
   693
            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
   694
77abe8dca695 further work on filesystem.py (path_from proto, stat, open, subdir-create, mkdir, subnodes
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
   695
            XXX: never used
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
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   698
        for node in self :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   699
            # figure out what type to use
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   700
            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
   701
                if test_func(node) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   702
                    # matches, build
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   703
                    yield node_type.from_node(node)
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   704
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   705
            else :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   706
                # unknown file type!
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   707
                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
   708
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   709
# assign default Directory.NODE_TYPES
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   710
Directory.NODE_TYPES = [
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   711
    (Node.is_dir,   Directory),
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   712
    (Node.is_file,  File),
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   713
]
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   714
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
class Root (Directory) :
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
        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
   719
    """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   720
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   721
    # XXX: config needs a default
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   722
    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
   723
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   724
            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
   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
        # abuse Node's concept of a "name" a bit
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   728
        super(Root, self).__init__(None, fspath)
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   729
        
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   730
        # store our config
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 68
diff changeset
   731
        self.config = config
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   732
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   733
    def nodepath (self) :
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   734
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   735
            Just return ourself
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   736
        """
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   737
        
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   738
        return [self]
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   739
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   740
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   741
    def path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   742
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   743
            Returns the raw path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   744
        """
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
        return self.fsname
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
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   749
    def unicodepath (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   750
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   751
            Returns the raw decoded path
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   752
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   753
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   754
        return self.name
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   755
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   756
    @property
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   757
    def root_path (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   758
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   759
            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
   760
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   761
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   762
        return ''
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   763
60
406da27a4be2 do some filesystem.Path stuff, and read_only mode
Tero Marttila <terom@fixme.fi>
parents: 55
diff changeset
   764
    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
   765
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   766
            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
   767
        """
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   768
        
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   769
        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
   770
51
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   771
    def __repr__ (self) :
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   772
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   773
            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
   774
        """
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   775
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   776
        return "Root(%r)" % self.fsname
0f39cb5e4b11 start writing new structure, with config, render, filesystem modules
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   777
79
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   778
# testing
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   779
if __name__ == '__main__' :
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   780
    import doctest
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   781
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   782
    doctest.testmod()
e5400304a3d3 fix filesystem.Path.path_segments and add some doctests
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   783