~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/vfs.py

  • Committer: John Arbash Meinel
  • Date: 2013-05-19 14:29:37 UTC
  • mfrom: (6437.63.9 2.5)
  • mto: (6437.63.10 2.5)
  • mto: This revision was merged to the branch mainline in revision 6575.
  • Revision ID: john@arbash-meinel.com-20130519142937-21ykz2n2y2f22za9
Merge in the actual 2.5 branch. It seems I failed before

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""VFS operations for the smart server.
18
18
 
24
24
protocol, as implemented in bzr 0.11 and later.
25
25
"""
26
26
 
 
27
from __future__ import absolute_import
 
28
 
27
29
import os
28
30
 
29
31
from bzrlib import errors
 
32
from bzrlib import urlutils
30
33
from bzrlib.smart import request
31
34
 
32
35
 
51
54
 
52
55
class VfsRequest(request.SmartServerRequest):
53
56
    """Base class for VFS requests.
54
 
    
 
57
 
55
58
    VFS requests are disabled if vfs_enabled() returns False.
56
59
    """
57
60
 
59
62
        if not vfs_enabled():
60
63
            raise errors.DisabledMethod(self.__class__.__name__)
61
64
 
 
65
    def translate_client_path(self, relpath):
 
66
        # VFS requests are made with escaped paths so the escaping done in
 
67
        # SmartServerRequest.translate_client_path leads to double escaping.
 
68
        # Remove it here -- the fact that the result is still escaped means
 
69
        # that the str() will not fail on valid input.
 
70
        x = request.SmartServerRequest.translate_client_path(self, relpath)
 
71
        return str(urlutils.unescape(x))
 
72
 
62
73
 
63
74
class HasRequest(VfsRequest):
64
75
 
65
76
    def do(self, relpath):
 
77
        relpath = self.translate_client_path(relpath)
66
78
        r = self._backing_transport.has(relpath) and 'yes' or 'no'
67
 
        return request.SmartServerResponse((r,))
 
79
        return request.SuccessfulSmartServerResponse((r,))
68
80
 
69
81
 
70
82
class GetRequest(VfsRequest):
71
83
 
72
84
    def do(self, relpath):
 
85
        relpath = self.translate_client_path(relpath)
73
86
        backing_bytes = self._backing_transport.get_bytes(relpath)
74
 
        return request.SmartServerResponse(('ok',), backing_bytes)
 
87
        return request.SuccessfulSmartServerResponse(('ok',), backing_bytes)
75
88
 
76
89
 
77
90
class AppendRequest(VfsRequest):
78
91
 
79
92
    def do(self, relpath, mode):
 
93
        relpath = self.translate_client_path(relpath)
80
94
        self._relpath = relpath
81
95
        self._mode = _deserialise_optional_mode(mode)
82
 
    
 
96
 
83
97
    def do_body(self, body_bytes):
84
98
        old_length = self._backing_transport.append_bytes(
85
99
            self._relpath, body_bytes, self._mode)
86
 
        return request.SmartServerResponse(('appended', '%d' % old_length))
 
100
        return request.SuccessfulSmartServerResponse(('appended', '%d' % old_length))
87
101
 
88
102
 
89
103
class DeleteRequest(VfsRequest):
90
104
 
91
105
    def do(self, relpath):
 
106
        relpath = self.translate_client_path(relpath)
92
107
        self._backing_transport.delete(relpath)
93
 
        return request.SmartServerResponse(('ok', ))
 
108
        return request.SuccessfulSmartServerResponse(('ok', ))
94
109
 
95
110
 
96
111
class IterFilesRecursiveRequest(VfsRequest):
97
112
 
98
113
    def do(self, relpath):
 
114
        if not relpath.endswith('/'):
 
115
            relpath += '/'
 
116
        relpath = self.translate_client_path(relpath)
99
117
        transport = self._backing_transport.clone(relpath)
100
118
        filenames = transport.iter_files_recursive()
101
 
        return request.SmartServerResponse(('names',) + tuple(filenames))
 
119
        return request.SuccessfulSmartServerResponse(('names',) + tuple(filenames))
102
120
 
103
121
 
104
122
class ListDirRequest(VfsRequest):
105
123
 
106
124
    def do(self, relpath):
 
125
        if not relpath.endswith('/'):
 
126
            relpath += '/'
 
127
        relpath = self.translate_client_path(relpath)
107
128
        filenames = self._backing_transport.list_dir(relpath)
108
 
        return request.SmartServerResponse(('names',) + tuple(filenames))
 
129
        return request.SuccessfulSmartServerResponse(('names',) + tuple(filenames))
109
130
 
110
131
 
111
132
class MkdirRequest(VfsRequest):
112
133
 
113
134
    def do(self, relpath, mode):
 
135
        relpath = self.translate_client_path(relpath)
114
136
        self._backing_transport.mkdir(relpath,
115
137
                                      _deserialise_optional_mode(mode))
116
 
        return request.SmartServerResponse(('ok',))
 
138
        return request.SuccessfulSmartServerResponse(('ok',))
117
139
 
118
140
 
119
141
class MoveRequest(VfsRequest):
120
142
 
121
143
    def do(self, rel_from, rel_to):
 
144
        rel_from = self.translate_client_path(rel_from)
 
145
        rel_to = self.translate_client_path(rel_to)
122
146
        self._backing_transport.move(rel_from, rel_to)
123
 
        return request.SmartServerResponse(('ok',))
 
147
        return request.SuccessfulSmartServerResponse(('ok',))
124
148
 
125
149
 
126
150
class PutRequest(VfsRequest):
127
151
 
128
152
    def do(self, relpath, mode):
 
153
        relpath = self.translate_client_path(relpath)
129
154
        self._relpath = relpath
130
155
        self._mode = _deserialise_optional_mode(mode)
131
156
 
132
157
    def do_body(self, body_bytes):
133
158
        self._backing_transport.put_bytes(self._relpath, body_bytes, self._mode)
134
 
        return request.SmartServerResponse(('ok',))
 
159
        return request.SuccessfulSmartServerResponse(('ok',))
135
160
 
136
161
 
137
162
class PutNonAtomicRequest(VfsRequest):
138
163
 
139
164
    def do(self, relpath, mode, create_parent, dir_mode):
 
165
        relpath = self.translate_client_path(relpath)
140
166
        self._relpath = relpath
141
167
        self._dir_mode = _deserialise_optional_mode(dir_mode)
142
168
        self._mode = _deserialise_optional_mode(mode)
149
175
                mode=self._mode,
150
176
                create_parent_dir=self._create_parent,
151
177
                dir_mode=self._dir_mode)
152
 
        return request.SmartServerResponse(('ok',))
 
178
        return request.SuccessfulSmartServerResponse(('ok',))
153
179
 
154
180
 
155
181
class ReadvRequest(VfsRequest):
156
182
 
157
183
    def do(self, relpath):
 
184
        relpath = self.translate_client_path(relpath)
158
185
        self._relpath = relpath
159
186
 
160
187
    def do_body(self, body_bytes):
162
189
        offsets = self._deserialise_offsets(body_bytes)
163
190
        backing_bytes = ''.join(bytes for offset, bytes in
164
191
            self._backing_transport.readv(self._relpath, offsets))
165
 
        return request.SmartServerResponse(('readv',), backing_bytes)
 
192
        return request.SuccessfulSmartServerResponse(('readv',), backing_bytes)
166
193
 
167
194
    def _deserialise_offsets(self, text):
168
195
        # XXX: FIXME this should be on the protocol object.
178
205
class RenameRequest(VfsRequest):
179
206
 
180
207
    def do(self, rel_from, rel_to):
 
208
        rel_from = self.translate_client_path(rel_from)
 
209
        rel_to = self.translate_client_path(rel_to)
181
210
        self._backing_transport.rename(rel_from, rel_to)
182
 
        return request.SmartServerResponse(('ok', ))
 
211
        return request.SuccessfulSmartServerResponse(('ok', ))
183
212
 
184
213
 
185
214
class RmdirRequest(VfsRequest):
186
215
 
187
216
    def do(self, relpath):
 
217
        relpath = self.translate_client_path(relpath)
188
218
        self._backing_transport.rmdir(relpath)
189
 
        return request.SmartServerResponse(('ok', ))
 
219
        return request.SuccessfulSmartServerResponse(('ok', ))
190
220
 
191
221
 
192
222
class StatRequest(VfsRequest):
193
223
 
194
224
    def do(self, relpath):
 
225
        if not relpath.endswith('/'):
 
226
            relpath += '/'
 
227
        relpath = self.translate_client_path(relpath)
195
228
        stat = self._backing_transport.stat(relpath)
196
 
        return request.SmartServerResponse(
 
229
        return request.SuccessfulSmartServerResponse(
197
230
            ('stat', str(stat.st_size), oct(stat.st_mode)))
198
231