~verterok/ubuntuone-client/tritcask-fix-825366-stable-3-0

« back to all changes in this revision

Viewing changes to ubuntuone/platform/windows/ipc_client.py

  • Committer: Tarmac
  • Author(s): Natalia B. Bidart
  • Date: 2011-11-02 19:54:16 UTC
  • mfrom: (1144.1.64 u1sdtool-multiplatform)
  • Revision ID: tarmac-20111102195416-7dsu24ku871u75dv
- Do not start more than one instance of ubuntuone-syncdaemon (removed buggy duplication of is_running method) (LP: #803672).
- Make u1sdtool multiplatform (LP: #868661).
- Provide feature parity for SyncDaemonTool between linux and windows (LP: #879561).
- Make SyncDaemonTool only fire returned deferreds when the operation is fully completed (LP: #879556, LP: #879558).
- Replace some of the mocker tests with regular tests (LP: #879564).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# -*- coding: utf-8 -*-
2
2
#
3
 
# Authors: Manuel de la Pena <manuel@canonical.com>
4
 
#          Alejandro J. Cura <alecu@canonical.com>
5
 
#
6
3
# Copyright 2011 Canonical Ltd.
7
4
#
8
5
# This program is free software: you can redistribute it and/or modify it
39
36
 
40
37
def remote(function):
41
38
    """Decorate the function to make the remote call."""
 
39
 
42
40
    @wraps(function)
43
 
    def remote_wrapper(*args, **kwargs):
 
41
    def remote_wrapper(self, *args, **kwargs):
44
42
        """Return the deferred for the remote call."""
45
 
        fixed_args = args[1:]
46
 
        logger.info('Performing %s as a remote call.', function.func_name)
47
 
        return args[0].remote.callRemote(function.func_name, *fixed_args,
48
 
                                         **kwargs)
 
43
        fname = function.__name__
 
44
        logger.debug('Performing %s as a remote call (%r, %r).',
 
45
                     fname, args, kwargs)
 
46
        return self.remote.callRemote(fname, *args, **kwargs)
 
47
 
49
48
    return remote_wrapper
50
49
 
51
50
 
52
51
def signal(function):
53
52
    """Decorate a function to perform the signal callback."""
 
53
 
54
54
    @wraps(function)
55
 
    def callback_wrapper(*args, **kwargs):
 
55
    def callback_wrapper(self, *args, **kwargs):
56
56
        """Return the result of the callback if present."""
57
 
        callback = getattr(args[0], function.func_name + '_cb', None)
 
57
        fname = function.__name__
 
58
        function(self, *args, **kwargs)
 
59
        callback = getattr(self, fname + '_cb', None)
58
60
        if callback is not None:
59
 
            fixed_args = args[1:]
60
 
            if not kwargs:
61
 
                return callback(*fixed_args)
62
 
            return callback(*fixed_args, **kwargs)
 
61
            return callback(*args, **kwargs)
 
62
 
63
63
    return callback_wrapper
64
64
 
65
65
 
83
83
 
84
84
 
85
85
class RemoteHandler(object, Referenceable):
86
 
    """Represents a handler that can be called so that is called remotely."""
 
86
    """A handler that can be called so that is called remotely."""
87
87
 
88
88
    def __init__(self, cb):
89
89
        """Create a new instance."""
143
143
        'on_metaqueue_changed',
144
144
    ]
145
145
 
146
 
    def __init__(self, remote_status):
147
 
        """Creates the instance."""
148
 
        super(StatusClient, self).__init__(remote_status)
149
 
 
150
146
    @remote
151
147
    def current_status(self):
152
 
        """Return the current status of the system, one of: local_rescan,
 
148
        """Return the current status of the system.
 
149
 
 
150
        The status can be one of: local_rescan,
153
151
        offline, trying_to_connect, server_rescan or online.
154
152
        """
155
153
 
158
156
        """Return a list of files with a download in progress."""
159
157
 
160
158
    @remote
 
159
    def free_space(self, vol_id):
 
160
        """Return the free space for the given volume."""
 
161
 
 
162
    @remote
161
163
    def waiting(self):
162
164
        """Return a list of the operations in action queue."""
163
165
 
177
179
 
178
180
    @remote
179
181
    def current_uploads(self):
180
 
        """ return a list of files with a upload in progress """
 
182
        """Return a list of files with a upload in progress."""
181
183
 
182
184
    @signal
183
185
    def on_content_queue_changed(self):
234
236
    __metaclass__ = RemoteMeta
235
237
 
236
238
    # calls that will be accessible remotely
237
 
    signal_handlers = ['on_event', ]
238
 
 
239
 
    def __init__(self, remote_events):
240
 
        """Creates the instance."""
241
 
        super(EventsClient, self).__init__(remote_events)
 
239
    signal_handlers = ['on_event']
242
240
 
243
241
    @remote
244
242
    def push_event(self, event_name, args):
257
255
    # calls that will be accessible remotely
258
256
    signal_handlers = ['on_root_mismatch', 'on_quota_exceeded']
259
257
 
260
 
    def __init__(self, remote_daemon):
261
 
        """Creates the instance."""
262
 
        super(SyncDaemonClient, self).__init__(remote_daemon)
263
 
 
264
258
    @remote
265
259
    def connect(self):
266
260
        """Connect to the server."""
267
261
 
268
262
    @remote
269
263
    def disconnect(self):
270
 
        """ Disconnect from the server. """
 
264
        """Disconnect from the server."""
271
265
 
272
266
    @remote
273
267
    def get_rootdir(self):
274
 
        """ Returns the root dir/mount point. """
 
268
        """Return the root dir/mount point."""
275
269
 
276
270
    @remote
277
271
    def get_sharesdir(self):
278
 
        """ Returns the shares dir/mount point. """
 
272
        """Return the shares dir/mount point."""
279
273
 
280
274
    @remote
281
275
    def get_sharesdir_link(self):
282
 
        """ Returns the shares dir/mount point. """
 
276
        """Return the shares dir/mount point. """
283
277
 
284
278
    @callbacks(callbacks_names=[('reply_handler', 2), ('error_handler', 3)])
285
279
    @remote
286
280
    def wait_for_nirvana(self, last_event_interval,
287
281
                         reply_handler=None, error_handler=None):
288
 
        """ call the reply handler when there are no more
289
 
        events or transfers.
290
 
        """
 
282
        """Call the reply handler when there are no more events/transfers."""
291
283
 
292
 
    @callbacks(callbacks_names=[('reply_handler', 1), ('error_handler', 2)])
293
284
    @remote
294
285
    def quit(self, reply_handler=None, error_handler=None):
295
 
        """ shutdown the syncdaemon. """
 
286
        """Shutdown the syncdaemon."""
296
287
 
297
288
    @remote
298
289
    def rescan_from_scratch(self, volume_id):
308
299
 
309
300
 
310
301
class FileSystemClient(RemoteClient):
311
 
    """ An ipc interface to the FileSystem Manager. """
312
 
 
313
 
    def __init__(self, remote_fs):
314
 
        """Creates the instance."""
315
 
        super(FileSystemClient, self).__init__(remote_fs)
 
302
    """An ipc interface to the FileSystem Manager."""
316
303
 
317
304
    @remote
318
305
    def get_metadata(self, path):
351
338
        'on_share_unsubscribe_error',
352
339
    ]
353
340
 
354
 
    def __init__(self, remote_shares):
355
 
        """Create the instance."""
356
 
        super(SharesClient, self).__init__(remote_shares)
357
 
 
358
341
    @remote
359
342
    def get_shares(self):
360
343
        """Return a list of dicts, each dict represents a share."""
361
344
 
362
 
    @callbacks(callbacks_names=[('reply_handler', 2), ('error_handler', 3)])
363
345
    @remote
364
346
    def accept_share(self, share_id, reply_handler=None, error_handler=None):
365
347
        """Accept a share.
369
351
 
370
352
        """
371
353
 
372
 
    @callbacks(callbacks_names=[('reply_handler', 2), ('error_handler', 3)])
373
354
    @remote
374
355
    def reject_share(self, share_id, reply_handler=None, error_handler=None):
375
356
        """Reject a share."""
388
369
 
389
370
    @remote
390
371
    def create_share(self, path, username, name, access_level):
391
 
        """ Share a subtree to the user identified by username.
 
372
        """Share a subtree to the user identified by username.
392
373
 
393
374
        @param path: that path to share (the root of the subtree)
394
375
        @param username: the username to offer the share to
408
389
 
409
390
    @remote
410
391
    def refresh_shares(self):
411
 
        """ Refresh the share list, requesting it to the server. """
 
392
        """Refresh the share list, requesting it to the server."""
412
393
 
413
394
    @remote
414
395
    def get_shared(self):
415
 
        """ returns a list of dicts, each dict represents a shared share.
 
396
        """Return a list of dicts, each dict represents a shared share.
 
397
 
416
398
        A share might not have the path set, as we might be still fetching the
417
399
        nodes from the server. In this cases the path is ''
418
400
        """
427
409
 
428
410
    @signal
429
411
    def on_share_delete_error(self, share, error):
430
 
        """Emits ShareDeleteError signal."""
 
412
        """Emit ShareDeleteError signal."""
431
413
 
432
414
    @signal
433
415
    def on_share_created(self, share_info):
434
 
        """ emits ShareCreated signal """
 
416
        """Emit ShareCreated signal."""
435
417
 
436
418
    @signal
437
419
    def on_share_create_error(self, share_info, error):
439
421
 
440
422
    @signal
441
423
    def on_share_answer_response(self, answer_info):
442
 
        """Emits ShareAnswerResponse signal."""
 
424
        """Emit ShareAnswerResponse signal."""
443
425
 
444
426
    @signal
445
427
    def on_new_share(self, share):
446
 
        """Emits NewShare signal."""
 
428
        """Emit NewShare signal."""
447
429
 
448
430
    @signal
449
431
    def on_share_subscribed(self, share):
450
 
        """Emit the ShareSubscribed signal"""
 
432
        """Emit the ShareSubscribed signal."""
451
433
 
452
434
    @signal
453
435
    def on_share_subscribe_error(self, share_id, error):
454
 
        """Emit the ShareSubscribeError signal"""
 
436
        """Emit the ShareSubscribeError signal."""
455
437
 
456
438
    @signal
457
439
    def on_share_unsubscribed(self, share):
458
 
        """Emit the ShareUnSubscribed signal"""
 
440
        """Emit the ShareUnSubscribed signal."""
459
441
 
460
442
    @signal
461
443
    def on_share_unsubscribe_error(self, share_id, error):
462
 
        """Emit the ShareUnSubscribeError signal"""
 
444
        """Emit the ShareUnSubscribeError signal."""
463
445
 
464
446
 
465
447
class ConfigClient(RemoteClient):
466
448
    """The Syncdaemon config/settings ipc interface. """
467
449
 
468
 
    def __init__(self, remote_config):
469
 
        """ Creates the instance."""
470
 
        super(ConfigClient, self).__init__(remote_config)
471
 
 
472
 
    @callbacks(callbacks_names=[('reply_handler', 1), ('error_handler', 2)])
473
450
    @remote
474
451
    def get_throttling_limits(self, reply_handler=None, error_handler=None):
475
452
        """Get the read/write limit from AQ and return a dict.
476
 
        Returns a dict(download=int, upload=int), if int is -1 the value isn't
 
453
 
 
454
        Return a dict(download=int, upload=int), if int is -1 the value isn't
477
455
        configured.
478
 
        The values are bytes/second
 
456
        The values are bytes/second.
479
457
        """
480
458
 
481
 
    @callbacks(callbacks_names=[('reply_handler', 3), ('error_handler', 4)])
482
459
    @remote
483
 
    def set_throttling_limits(self, download, upload,
484
 
                         reply_handler=None, error_handler=None):
 
460
    def set_throttling_limits(self, download, upload):
485
461
        """Set the read and write limits. The expected values are bytes/sec."""
486
462
 
487
 
    @callbacks(callbacks_names=[('reply_handler', 1), ('error_handler', 2)])
488
463
    @remote
489
 
    def enable_bandwidth_throttling(self, reply_handler=None,
490
 
                                    error_handler=None):
 
464
    def enable_bandwidth_throttling(self):
491
465
        """Enable bandwidth throttling."""
492
466
 
493
 
    @callbacks(callbacks_names=[('reply_handler', 1), ('error_handler', 2)])
494
467
    @remote
495
 
    def disable_bandwidth_throttling(self, reply_handler=None,
496
 
                                     error_handler=None):
 
468
    def disable_bandwidth_throttling(self):
497
469
        """Disable bandwidth throttling."""
498
470
 
499
 
    @callbacks(callbacks_names=[('reply_handler', 1), ('error_handler', 2)])
500
471
    @remote
501
 
    def bandwidth_throttling_enabled(self, reply_handler=None,
502
 
                                     error_handler=None):
503
 
        """Returns True (actually 1) if bandwidth throttling is enabled and
504
 
        False (0) otherwise.
505
 
        """
 
472
    def bandwidth_throttling_enabled(self):
 
473
        """Return if the bandwidth throttling is enabled."""
506
474
 
507
475
    @remote
508
476
    def udf_autosubscribe_enabled(self):
530
498
 
531
499
    @remote
532
500
    def set_files_sync_enabled(self, enabled):
533
 
        """Enable/disable file sync service."""
 
501
        """Enable/disable file sync service.
 
502
 
 
503
        DEPRECATED.
 
504
 
 
505
        """
534
506
 
535
507
    @remote
536
508
    def files_sync_enabled(self):
537
509
        """Return the files_sync_enabled config value."""
538
510
 
539
511
    @remote
 
512
    def enable_files_sync(self):
 
513
        """Enable the file sync service."""
 
514
 
 
515
    @remote
 
516
    def disable_files_sync(self):
 
517
        """Disable the file sync service."""
 
518
 
 
519
    @remote
540
520
    def autoconnect_enabled(self):
541
521
        """Return the autoconnect config value."""
542
522
 
543
523
    @remote
 
524
    def enable_autoconnect(self):
 
525
        """Enable the autoconnect config value."""
 
526
 
 
527
    @remote
 
528
    def disable_autoconnect(self):
 
529
        """Disable the autoconnect config value."""
 
530
 
 
531
    @remote
544
532
    def set_autoconnect_enabled(self, enabled):
545
 
        """Enable syncdaemon autoconnect."""
 
533
        """Enable syncdaemon autoconnect.
 
534
 
 
535
        DEPRECATED.
 
536
 
 
537
        """
546
538
 
547
539
    @remote
548
540
    def show_all_notifications_enabled(self):
574
566
        'on_folder_unsubscribe_error',
575
567
    ]
576
568
 
577
 
    def __init__(self, remote_folders):
578
 
        """Creates the instance."""
579
 
        super(FoldersClient, self).__init__(remote_folders)
580
 
 
581
569
    @remote
582
570
    def create(self, path):
583
571
        """Create a user defined folder in the specified path."""
600
588
 
601
589
    @remote
602
590
    def get_info(self, path):
603
 
        """Returns a dict containing the folder information."""
 
591
        """Return a dict containing the folder information."""
604
592
 
605
593
    @remote
606
594
    def refresh_volumes(self):
652
640
        'on_public_files_list_error',
653
641
    ]
654
642
 
655
 
    def __init__(self, remote_public_files):
656
 
        super(PublicFilesClient, self).__init__(remote_public_files)
657
 
 
658
643
    @remote
659
644
    def change_public_access(self, share_id, node_id, is_public):
660
645
        """Change the public access of a file."""
667
652
        """
668
653
 
669
654
    @signal
670
 
    def on_public_access_changed(self, share_id, node_id, is_public,
671
 
                                   public_url):
 
655
    def on_public_access_changed(self, file_info):
672
656
        """Emit the PublicAccessChanged signal."""
673
657
 
674
658
    @signal
675
 
    def on_public_access_change_error(self, share_id, node_id, error):
 
659
    def on_public_access_change_error(self, file_info, error):
676
660
        """Emit the PublicAccessChangeError signal."""
677
661
 
678
662
    @signal