~bzr-pqm/bzr/bzr.dev

907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1
#!/usr/bin/env python
2
"""\
3
An implementation of the Transport object for local
4
filesystem access.
5
"""
6
7
from bzrlib.transport import Transport, protocol_handlers
8
import os
9
10
class LocalTransport(Transport):
11
    """This is the transport agent for local filesystem access."""
12
13
    def __init__(self, base):
14
        """Set the base path where files will be stored."""
15
        from os.path import realpath
16
        super(LocalTransport, self).__init__(realpath(base))
17
907.1.22 by John Arbash Meinel
Fixed some encoding issues, added is_remote function for Transport objects.
18
    def is_remote(self):
19
        return False
20
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
21
    def clone(self, offset=None):
22
        """Return a new LocalTransport with root at self.base + offset
23
        Because the local filesystem does not require a connection, 
24
        we can just return a new object.
25
        """
26
        if offset is None:
27
            return LocalTransport(self.base)
28
        else:
29
            return LocalTransport(self.abspath(offset))
30
907.1.8 by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport
31
    def abspath(self, relpath):
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
32
        """Return the full url to the given relative path.
907.1.8 by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport
33
        This can be supplied with a string or a list
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
34
        """
907.1.8 by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport
35
        if isinstance(relpath, basestring):
36
            relpath = [relpath]
37
        return os.path.join(self.base, *relpath)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
38
39
    def has(self, relpath):
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
40
        return os.access(self.abspath(relpath), os.F_OK)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
41
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
42
    def get(self, relpath, decode=False):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
43
        """Get the file at the given relative path.
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
44
45
        :param relpath: The relative path to the file
46
        :param decode:  If True, assume the file is utf-8 encoded and
47
                        decode it into Unicode
48
        """
49
        if decode:
50
            import codecs
907.1.22 by John Arbash Meinel
Fixed some encoding issues, added is_remote function for Transport objects.
51
            return codecs.open(self.abspath(relpath), 'rb',
52
                    encoding='utf-8', buffering=60000)
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
53
        else:
54
            return open(self.abspath(relpath), 'rb')
55
56
    def put(self, relpath, f, encode=False):
57
        """Copy the file-like or string object into the location.
58
59
        :param relpath: Location to put the contents, relative to base.
60
        :param f:       File-like or string object.
61
        :param encode:  If True, translate the contents into utf-8 encoded text.
62
        """
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
63
        from bzrlib.atomicfile import AtomicFile
64
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
65
        if encode:
66
            fp = AtomicFile(self.abspath(relpath), 'wb', encoding='utf-8')
67
        else:
68
            fp = AtomicFile(self.abspath(relpath), 'wb')
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
69
        try:
70
            self._pump(f, fp)
71
            fp.commit()
72
        finally:
73
            fp.close()
74
75
    def mkdir(self, relpath):
76
        """Create a directory at the given path."""
77
        os.mkdir(self.abspath(relpath))
78
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
79
    def append(self, relpath, f):
80
        """Append the text in the file-like object into the final
81
        location.
82
        """
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
83
        fp = open(self.abspath(relpath), 'a+b')
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
84
        self._pump(f, fp)
85
86
    def copy(self, rel_from, rel_to):
87
        """Copy the item at rel_from to the location at rel_to"""
88
        import shutil
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
89
        path_from = self.abspath(rel_from)
90
        path_to = self.abspath(rel_to)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
91
        shutil.copy(path_from, path_to)
92
93
    def move(self, rel_from, rel_to):
94
        """Move the item at rel_from to the location at rel_to"""
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
95
        path_from = self.abspath(rel_from)
96
        path_to = self.abspath(rel_to)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
97
98
        os.rename(path_from, path_to)
99
100
    def delete(self, relpath):
101
        """Delete the item at relpath"""
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
102
        os.remove(self.abspath(relpath))
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
103
104
    def async_get(self, relpath):
105
        """Make a request for an file at the given location, but
106
        don't worry about actually getting it yet.
107
108
        :rtype: AsyncFile
109
        """
110
        raise NotImplementedError
111
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
112
    def list_dir(self, relpath):
113
        """Return a list of all files at the given location.
114
        WARNING: many transports do not support this, so trying avoid using
115
        it if at all possible.
116
        """
117
        return os.listdir(self.abspath(relpath))
118
119
    def stat(self, relpath):
120
        """Return the stat information for a file.
121
        """
122
        return os.stat(self.abspath(relpath))
123
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
124
# If nothing else matches, try the LocalTransport
125
protocol_handlers[None] = LocalTransport
126