31
33
gobject.set_application_name('u1sync')
33
35
from twisted.internet import reactor
34
from threading import Thread
36
from Queue import Queue
36
38
from ubuntuone.storageprotocol.oauth import OAuthToken
37
39
import ubuntuone.storageprotocol.dircontent_pb2 as dircontent_pb2
38
from ubuntuone.storageprotocol.dircontent_pb2 import DIRECTORY
40
from ubuntuone.storageprotocol.dircontent_pb2 import DIRECTORY, SYMLINK
39
41
from ubuntuone.u1sync.genericmerge import (
40
42
show_tree, generic_merge)
41
43
from ubuntuone.u1sync.client import (
42
44
ConnectionError, AuthenticationError, NoSuchShareError,
45
ForcedShutdown, Client)
44
46
from ubuntuone.u1sync.scan import scan_directory
45
47
from ubuntuone.u1sync.merge import (
46
48
SyncMerge, ClobberServerMerge, ClobberLocalMerge, merge_trees)
216
220
user = user.encode("utf-8")
217
221
print "%s %s (from %s) [%s]%s" % (id, name, user, access, status)
219
def do_diff(client, share_spec, directory, quiet, subtree_path):
223
def do_diff(client, share_spec, directory, quiet, subtree_path,
224
ignore_symlinks=True):
220
225
"""Diffs a local directory with the server."""
221
226
if share_spec is not None:
222
227
share_uuid = client.find_share(share_spec)
392
399
share_spec = None
394
reactor_thread = Thread(target=
395
lambda: reactor.run(installSignalHandlers=False))
396
reactor_thread.setDaemon(True)
397
reactor_thread.start()
399
401
client = Client(realm=options.realm, reactor=reactor)
402
should_create_token = (options.mode == "authorize")
403
token = client.obtain_oauth_token(create_token=should_create_token)
405
client.connect_ssl(options.host, int(options.port), options.no_ssl_verify)
408
client.set_capabilities()
409
client.oauth_from_token(token)
411
if options.mode == "sync":
412
do_sync(client=client, directory=directory, action=options.action,
413
dry_run=options.dry_run, quiet=options.quiet)
414
elif options.mode == "init":
415
do_init(client=client, share_spec=share_spec, directory=directory,
416
quiet=options.quiet, subtree_path=options.subtree)
417
elif options.mode == "list-shares":
418
do_list_shares(client=client)
419
elif options.mode == "diff":
420
do_diff(client=client, share_spec=share_spec, directory=directory,
421
quiet=options.quiet, subtree_path=options.subtree)
422
elif options.mode == "authorize":
423
if not options.quiet:
403
signal.signal(signal.SIGINT, lambda s, f: client.force_shutdown())
404
signal.signal(signal.SIGTERM, lambda s, f: client.force_shutdown())
407
"""Run the blocking client."""
408
if passed_token is None:
409
should_create_token = (options.mode == "authorize")
410
token = client.obtain_oauth_token(create_token=should_create_token)
414
client.connect_ssl(options.host, int(options.port), options.no_ssl_verify)
417
client.set_capabilities()
418
client.oauth_from_token(token)
420
if options.mode == "sync":
421
do_sync(client=client, directory=directory,
422
action=options.action,
423
dry_run=options.dry_run, quiet=options.quiet)
424
elif options.mode == "init":
425
do_init(client=client, share_spec=share_spec,
427
quiet=options.quiet, subtree_path=options.subtree)
428
elif options.mode == "list-shares":
429
do_list_shares(client=client)
430
elif options.mode == "diff":
431
do_diff(client=client, share_spec=share_spec,
433
quiet=options.quiet, subtree_path=options.subtree,
434
ignore_symlinks=False)
435
elif options.mode == "authorize":
436
if not options.quiet:
427
439
client.disconnect()
441
def capture_exception(queue, func):
442
"""Capture the exception from calling func."""
446
queue.put(sys.exc_info())
429
450
reactor.callWhenRunning(reactor.stop)
430
reactor_thread.join(1.0)
453
reactor.callInThread(capture_exception, queue, run_client)
454
reactor.run(installSignalHandlers=False)
455
exc_info = queue.get(True, 0.1)
457
raise exc_info[0], exc_info[1], exc_info[2]
433
460
"""Top-level main function."""