38
38
from warnings import warn
44
from bzrlib.trace import mutter, warning
40
45
from bzrlib.transport import (
45
import bzrlib.errors as errors
46
from bzrlib.trace import mutter, warning
49
52
_have_medusa = False
122
125
netloc = '%s@%s' % (urllib.quote(self._username), netloc)
123
126
if self._port is not None:
124
127
netloc = '%s:%d' % (netloc, self._port)
125
return urlparse.urlunparse(('ftp', netloc, path, '', '', ''))
131
return urlparse.urlunparse((proto, netloc, path, '', '', ''))
127
133
def _get_FTP(self):
128
134
"""Return the ftplib.FTP instance for this object."""
190
196
def _abspath(self, relpath):
191
197
assert isinstance(relpath, basestring)
192
relpath = urllib.unquote(relpath)
198
relpath = urlutils.unescape(relpath)
193
199
relpath_parts = relpath.split('/')
194
200
if len(relpath_parts) > 1:
195
201
if relpath_parts[0] == '':
212
218
# Possibly, we could use urlparse.urljoin() here, but
213
219
# I'm concerned about when it chooses to strip the last
214
220
# portion of the path, and when it doesn't.
215
return '/'.join(basepath) or '/'
222
# XXX: It seems that ftplib does not handle Unicode paths
223
# at the same time, medusa won't handle utf8 paths
224
# So if we .encode(utf8) here, then we get a Server failure.
225
# while if we use str(), we get a UnicodeError, and the test suite
226
# just skips testing UnicodePaths.
227
return str('/'.join(basepath) or '/')
217
229
def abspath(self, relpath):
218
230
"""Return the full url to the given relative path.
454
466
def list_dir(self, relpath):
455
467
"""See Transport.list_dir."""
468
basepath = self._abspath(relpath)
469
mutter("FTP nlst: %s", basepath)
457
mutter("FTP nlst: %s", self._abspath(relpath))
459
basepath = self._abspath(relpath)
460
472
paths = f.nlst(basepath)
461
# If FTP.nlst returns paths prefixed by relpath, strip 'em
462
if paths and paths[0].startswith(basepath):
463
paths = [path[len(basepath)+1:] for path in paths]
464
# Remove . and .. if present, and return
465
return [path for path in paths if path not in (".", "..")]
466
473
except ftplib.error_perm, e:
467
474
self._translate_perm_error(e, relpath, extra='error with list_dir')
475
# If FTP.nlst returns paths prefixed by relpath, strip 'em
476
if paths and paths[0].startswith(basepath):
477
entries = [path[len(basepath)+1:] for path in paths]
480
# Remove . and .. if present
481
return [urlutils.escape(entry) for entry in entries
482
if entry not in ('.', '..')]
469
484
def iter_files_recursive(self):
470
485
"""See Transport.iter_files_recursive.
473
488
mutter("FTP iter_files_recursive")
474
489
queue = list(self.list_dir("."))
476
relpath = urllib.quote(queue.pop(0))
491
relpath = queue.pop(0)
477
492
st = self.stat(relpath)
478
493
if stat.S_ISDIR(st.st_mode):
479
494
for i, basename in enumerate(self.list_dir(relpath)):