104
104
def write(self, bytes):
106
#Using pump_string_file seems to make things crash
106
# Using pump_string_file seems to make things crash
107
107
osutils.pumpfile(BytesIO(bytes), self.stream)
108
108
except gio.Error as e:
109
#self.transport._translate_gio_error(e,self.relpath)
109
# self.transport._translate_gio_error(e,self.relpath)
110
110
raise errors.BzrError(str(e))
132
132
raise ValueError(base)
134
134
(scheme, netloc, path, params, query, fragment) = \
135
urlparse(base[len('gio+'):], allow_fragments=False)
135
urlparse(base[len('gio+'):], allow_fragments=False)
136
136
if '@' in netloc:
137
137
user, netloc = netloc.rsplit('@', 1)
138
#Seems it is not possible to list supported backends for GIO
139
#so a hardcoded list it is then.
138
# Seems it is not possible to list supported backends for GIO
139
# so a hardcoded list it is then.
140
140
gio_backends = ['dav', 'file', 'ftp', 'obex', 'sftp', 'ssh', 'smb']
141
141
if scheme not in gio_backends:
142
142
raise urlutils.InvalidURL(base,
143
extra="GIO support is only available for " + \
144
', '.join(gio_backends))
143
extra="GIO support is only available for " +
144
', '.join(gio_backends))
146
#Remove the username and password from the url we send to GIO
147
#by rebuilding the url again.
146
# Remove the username and password from the url we send to GIO
147
# by rebuilding the url again.
148
148
u = (scheme, netloc, path, '', '', '')
149
149
self.url = urlunparse(u)
151
151
# And finally initialize super
152
152
super(GioTransport, self).__init__(base,
153
_from_transport=_from_transport)
153
_from_transport=_from_transport)
155
155
def _relpath_to_url(self, relpath):
156
156
full_url = urlutils.join(self.url, relpath)
173
173
def _auth_cb(self, op, message, default_user, default_domain, flags):
174
#really use breezy.auth get_password for this
175
#or possibly better gnome-keyring?
174
# really use breezy.auth get_password for this
175
# or possibly better gnome-keyring?
176
176
auth = config.AuthenticationConfig()
177
177
parsed_url = urlutils.URL.from_string(self.url)
181
181
prompt = (u'%s' % (parsed_url.scheme.upper(),) +
182
182
u' %(host)s DOMAIN\\username')
183
183
user_and_domain = auth.get_user(parsed_url.scheme,
184
parsed_url.host, port=parsed_url.port, ask=True,
184
parsed_url.host, port=parsed_url.port, ask=True,
186
186
(domain, user) = user_and_domain.split('\\', 1)
187
187
op.set_username(user)
188
188
op.set_domain(domain)
189
189
elif flags & gio.ASK_PASSWORD_NEED_USERNAME:
190
190
user = auth.get_user(parsed_url.scheme, parsed_url.host,
191
port=parsed_url.port, ask=True)
191
port=parsed_url.port, ask=True)
192
192
op.set_username(user)
193
193
elif flags & gio.ASK_PASSWORD_NEED_DOMAIN:
194
#Don't know how common this case is, but anyway
195
#a DOMAIN and a username prompt should be the
196
#same so I will missuse the ui_factory get_username
194
# Don't know how common this case is, but anyway
195
# a DOMAIN and a username prompt should be the
196
# same so I will missuse the ui_factory get_username
198
198
prompt = (u'%s' % (parsed_url.scheme.upper(),) +
199
199
u' %(host)s DOMAIN')
200
200
domain = ui.ui_factory.get_username(prompt=prompt)
205
205
user = op.get_username()
206
206
password = auth.get_password(parsed_url.scheme, parsed_url.host,
207
user, port=parsed_url.port)
207
user, port=parsed_url.port)
208
208
op.set_password(password)
209
209
op.reply(gio.MOUNT_OPERATION_HANDLED)
230
231
except gio.Error as e:
231
232
if (e.code == gio.ERROR_NOT_MOUNTED):
232
233
self.loop = glib.MainLoop()
233
ui.ui_factory.show_message('Mounting %s using GIO' % \
234
ui.ui_factory.show_message('Mounting %s using GIO' %
235
236
op = gio.MountOperation()
237
238
op.set_username(user)
239
240
op.set_password(password)
240
241
op.connect('ask-password', self._auth_cb)
241
242
m = connection.mount_enclosing_volume(op,
244
245
except gio.Error as e:
245
246
raise errors.TransportError(msg="Error setting up connection:"
297
298
return BytesIO(buf)
298
299
except gio.Error as e:
299
#If we get a not mounted here it might mean
300
#that a bad path has been entered (or that mount failed)
300
# If we get a not mounted here it might mean
301
# that a bad path has been entered (or that mount failed)
301
302
if (e.code == gio.ERROR_NOT_MOUNTED):
302
303
raise errors.PathError(relpath,
303
extra='Failed to get file, make sure the path is correct. ' \
304
extra='Failed to get file, make sure the path is correct. '
306
307
self._translate_gio_error(e, relpath)
314
315
if 'gio' in debug.debug_flags:
315
316
mutter("GIO put_file %s" % relpath)
316
317
tmppath = '%s.tmp.%.9f.%d.%d' % (relpath, time.time(),
317
os.getpid(), random.randint(0, 0x7FFFFFFF))
318
os.getpid(), random.randint(0, 0x7FFFFFFF))
396
397
"""Append the text in the file-like object into the final
399
#GIO append_to seems not to append but to truncate
400
# GIO append_to seems not to append but to truncate
401
402
if 'gio' in debug.debug_flags:
402
403
mutter("GIO append_file: %s" % relpath)
403
404
tmppath = '%s.tmp.%.9f.%d.%d' % (relpath, time.time(),
404
os.getpid(), random.randint(0, 0x7FFFFFFF))
405
os.getpid(), random.randint(0, 0x7FFFFFFF))
407
408
fo = self._get_GIO(tmppath)
414
415
self._pump(fin, fout)
416
#This separate except is to catch and ignore the
417
#gio.ERROR_NOT_FOUND for the already existing file.
418
#It is valid to open a non-existing file for append.
419
#This is caused by the broken gio append_to...
417
# This separate except is to catch and ignore the
418
# gio.ERROR_NOT_FOUND for the already existing file.
419
# It is valid to open a non-existing file for append.
420
# This is caused by the broken gio append_to...
420
421
except gio.Error as e:
421
422
if e.code != gio.ERROR_NOT_FOUND:
422
423
self._translate_gio_error(e, relpath)
425
426
info = GioStatResult(fo)
426
427
if info.st_size != result + length:
427
raise errors.BzrError("Failed to append size after " \
428
"(%d) is not original (%d) + written (%d) total (%d)" % \
429
(info.st_size, result, length, result + length))
428
raise errors.BzrError("Failed to append size after "
429
"(%d) is not original (%d) + written (%d) total (%d)" %
430
(info.st_size, result, length, result + length))
430
431
fo.move(fi, flags=gio.FILE_COPY_OVERWRITE)
432
433
except gio.Error as e:
447
448
if e.code == gio.ERROR_NOT_SUPPORTED:
448
449
# Command probably not available on this server
449
450
mutter("GIO Could not set permissions to %s on %s. %s",
450
oct(mode), self._remote_path(relpath), str(e))
451
oct(mode), self._remote_path(relpath), str(e))
452
453
self._translate_gio_error(e, relpath)
590
591
mutter('unable to understand error for path: %s: %s', path, err)
591
592
raise errors.PathError(path,
592
extra="Unhandled gio error: " + str(err))
593
extra="Unhandled gio error: " + str(err))
595
596
def get_test_permutations():