Merge lp:~diegosarmentero/ubuntuone-client/darwin-os-helper into lp:ubuntuone-client

Proposed by Diego Sarmentero
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 1261
Merged at revision: 1246
Proposed branch: lp:~diegosarmentero/ubuntuone-client/darwin-os-helper
Merge into: lp:ubuntuone-client
Diff against target: 1108 lines (+777/-149)
20 files modified
Makefile.am (+3/-3)
run-mac-tests (+47/-0)
run-tests.bat (+2/-2)
tests/platform/__init__.py (+5/-2)
tests/platform/ipc/test_darwin.py (+65/-0)
tests/platform/os_helper/test_darwin.py (+104/-0)
ubuntuone/platform/filesystem_notifications/__init__.py (+4/-0)
ubuntuone/platform/filesystem_notifications/darwin.py (+37/-0)
ubuntuone/platform/ipc/__init__.py (+3/-0)
ubuntuone/platform/ipc/darwin.py (+44/-0)
ubuntuone/platform/logger/__init__.py (+3/-0)
ubuntuone/platform/logger/darwin.py (+37/-0)
ubuntuone/platform/os_helper/__init__.py (+3/-0)
ubuntuone/platform/os_helper/darwin.py (+110/-0)
ubuntuone/platform/os_helper/linux.py (+28/-142)
ubuntuone/platform/os_helper/unix.py (+186/-0)
ubuntuone/platform/session/__init__.py (+3/-0)
ubuntuone/platform/session/darwin.py (+43/-0)
ubuntuone/platform/tools/__init__.py (+3/-0)
ubuntuone/platform/tools/darwin.py (+47/-0)
To merge this branch: bzr merge lp:~diegosarmentero/ubuntuone-client/darwin-os-helper
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
Mike McCracken (community) Approve
Review via email: mp+106014@code.launchpad.net

Commit message

- Adding MAC OS implementation for platform/os_helper

Description of the change

To run the tests on MAC OS you need to install ubuntuone-storage-protocol, and execute the tests like this:

./run-mac-tests tests/platform/os_helper/

os_helper is the only thing that is working in mac right now, the other modules have dummy implementations to avoid failures with the imports.

To post a comment you must log in.
1257. By Diego Sarmentero

reverting and modifying run-tests.bat file

Revision history for this message
Mike McCracken (mikemc) wrote :

Two things:

1. the docstring for common.py still says it's for linux

2. os_helper/darwin.py :
move_to_trash() currently always moves to ~/.Trash, which is OK if the file is on the root filesystem, but if it's mounted on a separate volume, it should go into that volume's .Trashes directory at /Volumes/volume_name_goes_here/.Trashes/my_uid_here/file.

This will be useful for folders outside home. I believe it's possible to have home on a separately mounted drive, but I doubt that too many people do that.

It also needs a check for non-existent paths, or else it'll catch the IOError in shutil.move() and try to os.remove() a non-existent path.

Might also want a test for non-existent name handling.

I wrote a version of move_to_trash with /Volumes/ handling a while ago that I never ran because of all the test errors. It had BUGS. I just fixed it, added throwing a useful exception on nonexistent paths, and posted it here: http://paste.ubuntu.com/991189/
it should plug right in, if you'd like to use it.

review: Needs Fixing
Revision history for this message
Manuel de la Peña (mandel) wrote :

Adding to the great comments from Mike. I think using the name common is a little misleading, what about unix.py or nix.py to state that is for the *nix flavors of the code.

There are a number of copyrights that are wrong, for example:

115 +# Copyright 2009-2012 Canonical Ltd.

But test_darwin was not there until 2012, or were you hiding it? :)

review: Needs Fixing
1258. By Diego Sarmentero

Improving move_to_trash, adding new tests

1259. By Diego Sarmentero

Fixing Files header.

1260. By Diego Sarmentero

Fixing move_to_trash not existing file test

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> Adding to the great comments from Mike. I think using the name common is a
> little misleading, what about unix.py or nix.py to state that is for the *nix
> flavors of the code.
>
> There are a number of copyrights that are wrong, for example:
>
> 115 +# Copyright 2009-2012 Canonical Ltd.
>
> But test_darwin was not there until 2012, or were you hiding it? :)

Fixed

1261. By Diego Sarmentero

Fixing os_helper tests

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> Two things:
>
> 1. the docstring for common.py still says it's for linux
>
> 2. os_helper/darwin.py :
> move_to_trash() currently always moves to ~/.Trash, which is OK if the file is
> on the root filesystem, but if it's mounted on a separate volume, it should go
> into that volume's .Trashes directory at
> /Volumes/volume_name_goes_here/.Trashes/my_uid_here/file.
>
> This will be useful for folders outside home. I believe it's possible to have
> home on a separately mounted drive, but I doubt that too many people do that.
>
> It also needs a check for non-existent paths, or else it'll catch the IOError
> in shutil.move() and try to os.remove() a non-existent path.
>
> Might also want a test for non-existent name handling.
>
> I wrote a version of move_to_trash with /Volumes/ handling a while ago that I
> never ran because of all the test errors. It had BUGS. I just fixed it, added
> throwing a useful exception on nonexistent paths, and posted it here:
> http://paste.ubuntu.com/991189/
> it should plug right in, if you'd like to use it.

Fixed

Revision history for this message
Mike McCracken (mikemc) wrote :

+1

review: Approve
Revision history for this message
Manuel de la Peña (mandel) wrote :

Looks good but I wonder if there is a nicer way to do the following:

529 +set_no_rights = unix.set_no_rights
530 +set_file_readonly = unix.set_file_readonly
531 +set_file_readwrite = unix.set_file_readwrite
532 +set_dir_readonly = unix.set_dir_readonly
533 +set_dir_readwrite = unix.set_dir_readwrite
534 +allow_writes = unix.allow_writes
535 +remove_file = unix.remove_file
536 +remove_tree = unix.remove_tree
537 +remove_dir = unix.remove_dir
538 +path_exists = unix.path_exists
539 +make_dir = unix.make_dir
540 +open_file = unix.open_file
541 +rename = unix.rename
542 +native_rename = unix.native_rename
543 +recursive_move = unix.recursive_move
544 +make_link = unix.make_link
545 +read_link = unix.read_link
546 +is_link = unix.is_link
547 +remove_link = unix.remove_link
548 +listdir = unix.listdir
549 +walk = unix.walk
550 +access = unix.access
551 +can_write = unix.can_write
552 +stat_path = unix.stat_path
553 +is_root = unix.is_root
554 +get_path_list = unix.get_path_list
555 +normpath = unix.normpath

I know that simply importing the functions will make them accessible via the darwin package, is there a reason why you are doing it this way? (pyflakes maybe?)

review: Needs Fixing
Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> Looks good but I wonder if there is a nicer way to do the following:
>
> 529 +set_no_rights = unix.set_no_rights
> 530 +set_file_readonly = unix.set_file_readonly
> 531 +set_file_readwrite = unix.set_file_readwrite
> 532 +set_dir_readonly = unix.set_dir_readonly
> 533 +set_dir_readwrite = unix.set_dir_readwrite
> 534 +allow_writes = unix.allow_writes
> 535 +remove_file = unix.remove_file
> 536 +remove_tree = unix.remove_tree
> 537 +remove_dir = unix.remove_dir
> 538 +path_exists = unix.path_exists
> 539 +make_dir = unix.make_dir
> 540 +open_file = unix.open_file
> 541 +rename = unix.rename
> 542 +native_rename = unix.native_rename
> 543 +recursive_move = unix.recursive_move
> 544 +make_link = unix.make_link
> 545 +read_link = unix.read_link
> 546 +is_link = unix.is_link
> 547 +remove_link = unix.remove_link
> 548 +listdir = unix.listdir
> 549 +walk = unix.walk
> 550 +access = unix.access
> 551 +can_write = unix.can_write
> 552 +stat_path = unix.stat_path
> 553 +is_root = unix.is_root
> 554 +get_path_list = unix.get_path_list
> 555 +normpath = unix.normpath
>
> I know that simply importing the functions will make them accessible via the
> darwin package, is there a reason why you are doing it this way? (pyflakes
> maybe?)

Yes, pyflakes will say something like:

./ubuntuone/platform/os_helper/linux.py:
    51: 'rename' imported but unused
    51: 'walk' imported but unused
    51: 'set_dir_readwrite' imported but unused
    51: 'allow_writes' imported but unused
    51: 'is_link' imported but unused
    51: 'set_file_readwrite' imported but unused
    51: 'path_exists' imported but unused
    51: 'open_file' imported but unused
    51: 'set_no_rights' imported but unused
    51: 'access' imported but unused
    51: 'read_link' imported but unused
    51: 'remove_dir' imported but unused
    51: 'set_file_readonly' imported but unused
    51: 'listdir' imported but unused
    51: 'can_write' imported but unused
    51: 'remove_tree' imported but unused
    51: 'make_link' imported but unused
    51: 'make_dir' imported but unused
    51: 'native_rename' imported but unused
    51: 'get_path_list' imported but unused
    51: 'recursive_move' imported but unused
    51: 'is_root' imported but unused
    51: 'remove_link' imported but unused
    51: 'normpath' imported but unused
    51: 'set_dir_readonly' imported but unused
    51: 'remove_file' imported but unused
    51: 'stat_path' imported but unused

make: *** [lint] Error 53

Revision history for this message
Manuel de la Peña (mandel) wrote :

Ok, then +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2012-05-02 21:53:57 +0000
3+++ Makefile.am 2012-05-17 12:59:18 +0000
4@@ -54,14 +54,14 @@
5 test: logging.conf $(clientdefs_DATA) Makefile
6 echo "$(PYTHONPATH)"
7 if test "x$(builddir)" == "x$(srcdir)"; then \
8- PYTHONPATH="$(PYTHONPATH)" u1trial -r $(REACTOR) -p tests/platform/windows,tests/proxy -i test_windows.py tests || exit 1; \
9- PYTHONPATH="$(PYTHONPATH)" u1trial -r qt4 -p tests/platform/windows -i test_windows.py tests/proxy || exit 1; \
10+ PYTHONPATH="$(PYTHONPATH)" u1trial -r $(REACTOR) -p tests/platform/windows,tests/proxy -i "test_windows.py,test_darwin.py" tests || exit 1; \
11+ PYTHONPATH="$(PYTHONPATH)" u1trial -r qt4 -p tests/platform/windows -i "test_windows.py,test_darwin.py" tests/proxy || exit 1; \
12 fi
13 rm -rf _trial_temp
14
15 test-coverage: logging.conf $(clientdefs_DATA) Makefile
16 if test "x$(builddir)" == "x$(srcdir)"; then \
17- PYTHONPATH="$(PYTHONPATH)" u1trial -r $(REACTOR) -c -p tests/platform/windows -i test_windows.py tests; \
18+ PYTHONPATH="$(PYTHONPATH)" u1trial -r $(REACTOR) -c -p tests/platform/windows -i "test_windows.py,test_darwin.py" tests; \
19 fi
20 rm -rf _trial_temp
21
22
23=== added file 'run-mac-tests'
24--- run-mac-tests 1970-01-01 00:00:00 +0000
25+++ run-mac-tests 2012-05-17 12:59:18 +0000
26@@ -0,0 +1,47 @@
27+#! /bin/bash
28+#
29+# Copyright 2012 Canonical Ltd.
30+#
31+# This program is free software: you can redistribute it and/or modify it
32+# under the terms of the GNU General Public License version 3, as published
33+# by the Free Software Foundation.
34+#
35+# This program is distributed in the hope that it will be useful, but
36+# WITHOUT ANY WARRANTY; without even the implied warranties of
37+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
38+# PURPOSE. See the GNU General Public License for more details.
39+#
40+# You should have received a copy of the GNU General Public License along
41+# with this program. If not, see <http://www.gnu.org/licenses/>.
42+#
43+# In addition, as a special exception, the copyright holders give
44+# permission to link the code of portions of this program with the
45+# OpenSSL library under certain conditions as described in each
46+# individual source file, and distribute linked combinations
47+# including the two.
48+# You must obey the GNU General Public License in all respects
49+# for all of the code used other than OpenSSL. If you modify
50+# file(s) with this exception, you may extend this exception to your
51+# version of the file(s), but you are not obligated to do so. If you
52+# do not wish to do so, delete this exception statement from your
53+# version. If you delete this exception statement from all source
54+# files in the program, then also delete it here.
55+
56+PYTHONPATH=../ubuntu-sso-client/:$PYTHONPATH
57+
58+set -e
59+if [ $# -ne 0 ]; then
60+ # run specific module given by the caller
61+ MODULE="$@"
62+else
63+ # run all tests, useful for tarmac and reviews
64+ MODULE="tests"
65+fi
66+
67+echo "Executing the tests..."
68+cp windows/clientdefs.py ubuntuone/clientdefs.py
69+cp windows/logging.conf data/logging.conf
70+# execute the tests with a number of ignored linux only modules
71+python $u1trial --reactor=twisted -i "test_linux.py,test_windows.py" "$MODULE"
72+rm -rf _trial_temp
73+rm -rf build
74
75=== modified file 'run-tests.bat'
76--- run-tests.bat 2012-04-27 19:38:24 +0000
77+++ run-tests.bat 2012-05-17 12:59:18 +0000
78@@ -73,8 +73,8 @@
79 ECHO Python found, executing the tests...
80 COPY windows\clientdefs.py ubuntuone\clientdefs.py
81 COPY windows\logging.conf data\logging.conf
82-:: execute the tests with a number of ignored linux only modules
83-"%PYTHONEXEPATH%" "%TRIALPATH%" --reactor=twisted -c -p tests\platform\linux -i test_linux.py %PARAMS% tests
84+:: execute the tests with a number of ignored linux and mac os only modules
85+"%PYTHONEXEPATH%" "%TRIALPATH%" --reactor=twisted -c -p tests\platform\linux -i "test_linux.py,test_darwin.py" %PARAMS% tests
86
87 IF %SKIPLINT% == 1 (
88 ECHO Skipping style checks
89
90=== modified file 'tests/platform/__init__.py'
91--- tests/platform/__init__.py 2012-05-02 19:07:59 +0000
92+++ tests/platform/__init__.py 2012-05-17 12:59:18 +0000
93@@ -29,9 +29,12 @@
94
95 if sys.platform.startswith('linux'):
96 from tests.platform.ipc import test_linux
97- ipc_source = test_linux
98+ ipc_source = test_linux
99+elif sys.platform == 'darwin':
100+ from tests.platform.ipc import test_darwin
101+ ipc_source = test_darwin
102 else:
103- from tests.platform.ipc import test_windows
104+ from tests.platform.ipc import test_windows
105 ipc_source = test_windows
106
107 IPCTestCase = ipc_source.IPCTestCase
108
109=== added file 'tests/platform/ipc/test_darwin.py'
110--- tests/platform/ipc/test_darwin.py 1970-01-01 00:00:00 +0000
111+++ tests/platform/ipc/test_darwin.py 2012-05-17 12:59:18 +0000
112@@ -0,0 +1,65 @@
113+# -*- coding: utf-8 -*-
114+#
115+# Copyright 2012 Canonical Ltd.
116+#
117+# This program is free software: you can redistribute it and/or modify it
118+# under the terms of the GNU General Public License version 3, as published
119+# by the Free Software Foundation.
120+#
121+# This program is distributed in the hope that it will be useful, but
122+# WITHOUT ANY WARRANTY; without even the implied warranties of
123+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
124+# PURPOSE. See the GNU General Public License for more details.
125+#
126+# You should have received a copy of the GNU General Public License along
127+# with this program. If not, see <http://www.gnu.org/licenses/>.
128+#
129+# In addition, as a special exception, the copyright holders give
130+# permission to link the code of portions of this program with the
131+# OpenSSL library under certain conditions as described in each
132+# individual source file, and distribute linked combinations
133+# including the two.
134+# You must obey the GNU General Public License in all respects
135+# for all of the code used other than OpenSSL. If you modify
136+# file(s) with this exception, you may extend this exception to your
137+# version of the file(s), but you are not obligated to do so. If you
138+# do not wish to do so, delete this exception statement from your
139+# version. If you delete this exception statement from all source
140+# files in the program, then also delete it here.
141+"""Tests for the IPC interface."""
142+
143+
144+class IPCTestCase(object):
145+ """Empty Implementation"""
146+
147+
148+class StatusTestCase(object):
149+ """Empty Implementation"""
150+
151+
152+class EventsTestCase(object):
153+ """Empty Implementation"""
154+
155+
156+class SyncDaemonTestCase(object):
157+ """Empty Implementation"""
158+
159+
160+class FileSystemTestCase(object):
161+ """Empty Implementation"""
162+
163+
164+class SharesTestCase(object):
165+ """Empty Implementation"""
166+
167+
168+class ConfigTestCase(object):
169+ """Empty Implementation"""
170+
171+
172+class FoldersTestCase(object):
173+ """Empty Implementation"""
174+
175+
176+class PublicFilesTestCase(object):
177+ """Empty Implementation"""
178
179=== added file 'tests/platform/os_helper/test_darwin.py'
180--- tests/platform/os_helper/test_darwin.py 1970-01-01 00:00:00 +0000
181+++ tests/platform/os_helper/test_darwin.py 2012-05-17 12:59:18 +0000
182@@ -0,0 +1,104 @@
183+# tests.platform.os_helper - darwin platform tests
184+#
185+# Copyright 2012 Canonical Ltd.
186+#
187+# This program is free software: you can redistribute it and/or modify it
188+# under the terms of the GNU General Public License version 3, as published
189+# by the Free Software Foundation.
190+#
191+# This program is distributed in the hope that it will be useful, but
192+# WITHOUT ANY WARRANTY; without even the implied warranties of
193+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
194+# PURPOSE. See the GNU General Public License for more details.
195+#
196+# You should have received a copy of the GNU General Public License along
197+# with this program. If not, see <http://www.gnu.org/licenses/>.
198+#
199+# In addition, as a special exception, the copyright holders give
200+# permission to link the code of portions of this program with the
201+# OpenSSL library under certain conditions as described in each
202+# individual source file, and distribute linked combinations
203+# including the two.
204+# You must obey the GNU General Public License in all respects
205+# for all of the code used other than OpenSSL. If you modify
206+# file(s) with this exception, you may extend this exception to your
207+# version of the file(s), but you are not obligated to do so. If you
208+# do not wish to do so, delete this exception statement from your
209+# version. If you delete this exception statement from all source
210+# files in the program, then also delete it here.
211+"""Darwin specific tests for the platform module."""
212+
213+import logging
214+import os
215+
216+from twisted.internet import defer
217+from ubuntuone.devtools.handlers import MementoHandler
218+
219+from tests.platform.os_helper import test_os_helper
220+from ubuntuone.platform.os_helper import darwin
221+from ubuntuone.platform import (
222+ move_to_trash,
223+ open_file,
224+ set_application_name,
225+ stat_path,
226+)
227+
228+
229+class OSWrapperTests(test_os_helper.OSWrapperTests):
230+ """Tests for os wrapper functions."""
231+
232+ @defer.inlineCallbacks
233+ def setUp(self):
234+ """Set up."""
235+ yield super(OSWrapperTests, self).setUp()
236+ self.handler = MementoHandler()
237+ self.handler.setLevel(logging.DEBUG)
238+ self._logger = logging.getLogger('ubuntuone.SyncDaemon')
239+ self._logger.addHandler(self.handler)
240+ self.addCleanup(self._logger.removeHandler, self.handler)
241+ self.patch(darwin.shutil, "move", self._fake_move)
242+
243+ def _fake_move(*args):
244+ """Fake shutil move."""
245+ raise Exception("Fail fake move")
246+
247+ def test_stat_symlink(self):
248+ """Test that it doesn't follow symlinks.
249+
250+ We compare the inode only (enough to see if it's returning info
251+ from the link or the linked), as we can not compare the full stat
252+ because the st_mode will be different.
253+ """
254+ link = os.path.join(self.basedir, 'foo')
255+ os.symlink(self.testfile, link)
256+ self.assertNotEqual(os.stat(link).st_ino, stat_path(link).st_ino)
257+ self.assertEqual(os.lstat(link).st_ino, stat_path(link).st_ino)
258+
259+ def test_set_application_name(self):
260+ """Check that the implementation of set_application_name fails."""
261+ self.assertRaises(Exception, set_application_name, "test")
262+
263+ def test_movetotrash_file_bad(self):
264+ """Something bad happen when moving to trash, removed anyway."""
265+ path = os.path.join(self.basedir, 'foo')
266+ open_file(path, 'w').close()
267+ move_to_trash(path)
268+ self.assertFalse(os.path.exists(path))
269+ self.assertTrue(self.handler.check_warning("Problems moving to trash!",
270+ "Removing anyway", "foo"))
271+
272+ def test_movetotrash_file_not_exists(self):
273+ """Something bad happen when moving to trash, removed anyway."""
274+ path = os.path.join(self.basedir, 'foo2')
275+ self.assertFalse(os.path.exists(path))
276+ self.assertRaises(OSError, move_to_trash, path)
277+
278+ def test_movetotrash_dir_bad(self):
279+ """Something bad happen when moving to trash, removed anyway."""
280+ path = os.path.join(self.basedir, 'foo')
281+ os.mkdir(path)
282+ open_file(os.path.join(path, 'file inside directory'), 'w').close()
283+ move_to_trash(path)
284+ self.assertFalse(os.path.exists(path))
285+ self.assertTrue(self.handler.check_warning("Problems moving to trash!",
286+ "Removing anyway", "foo"))
287
288=== modified file 'ubuntuone/platform/filesystem_notifications/__init__.py'
289--- ubuntuone/platform/filesystem_notifications/__init__.py 2012-05-14 21:24:24 +0000
290+++ ubuntuone/platform/filesystem_notifications/__init__.py 2012-05-17 12:59:18 +0000
291@@ -35,6 +35,10 @@
292 from ubuntuone.platform.filesystem_notifications import windows
293 FilesystemMonitor = windows.FilesystemMonitor
294 _GeneralINotifyProcessor = windows.NotifyProcessor
295+elif sys.platform == "darwin":
296+ from ubuntuone.platform.filesystem_notifications import darwin
297+ FilesystemMonitor = darwin.FilesystemMonitor
298+ _GeneralINotifyProcessor = darwin.NotifyProcessor
299 else:
300 from ubuntuone.platform.filesystem_notifications import linux
301 FilesystemMonitor = linux.FilesystemMonitor
302
303=== added file 'ubuntuone/platform/filesystem_notifications/darwin.py'
304--- ubuntuone/platform/filesystem_notifications/darwin.py 1970-01-01 00:00:00 +0000
305+++ ubuntuone/platform/filesystem_notifications/darwin.py 2012-05-17 12:59:18 +0000
306@@ -0,0 +1,37 @@
307+# -*- coding: utf-8 *-*
308+#
309+# Copyright 2012 Canonical Ltd.
310+#
311+# This program is free software: you can redistribute it and/or modify it
312+# under the terms of the GNU General Public License version 3, as published
313+# by the Free Software Foundation.
314+#
315+# This program is distributed in the hope that it will be useful, but
316+# WITHOUT ANY WARRANTY; without even the implied warranties of
317+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
318+# PURPOSE. See the GNU General Public License for more details.
319+#
320+# You should have received a copy of the GNU General Public License along
321+# with this program. If not, see <http://www.gnu.org/licenses/>.
322+#
323+# In addition, as a special exception, the copyright holders give
324+# permission to link the code of portions of this program with the
325+# OpenSSL library under certain conditions as described in each
326+# individual source file, and distribute linked combinations
327+# including the two.
328+# You must obey the GNU General Public License in all respects
329+# for all of the code used other than OpenSSL. If you modify
330+# file(s) with this exception, you may extend this exception to your
331+# version of the file(s), but you are not obligated to do so. If you
332+# do not wish to do so, delete this exception statement from your
333+# version. If you delete this exception statement from all source
334+# files in the program, then also delete it here.
335+"""Filesystem Notifications module for MAC OS."""
336+
337+
338+class FilesystemMonitor(object):
339+ """Empty implementation of FilesystemMonitor"""
340+
341+
342+class NotifyProcessor(object):
343+ """Empty implementation of NotifyProcessor"""
344
345=== modified file 'ubuntuone/platform/ipc/__init__.py'
346--- ubuntuone/platform/ipc/__init__.py 2012-05-01 11:39:00 +0000
347+++ ubuntuone/platform/ipc/__init__.py 2012-05-17 12:59:18 +0000
348@@ -34,6 +34,9 @@
349 if sys.platform == "win32":
350 from ubuntuone.platform.ipc import windows as source
351 ExternalInterface = source.IPCInterface
352+elif sys.platform == "darwin":
353+ from ubuntuone.platform.ipc import darwin as source
354+ ExternalInterface = source.IPCInterface
355 else:
356 from ubuntuone.platform.ipc import linux as source
357 ExternalInterface = source.DBusInterface
358
359=== added file 'ubuntuone/platform/ipc/darwin.py'
360--- ubuntuone/platform/ipc/darwin.py 1970-01-01 00:00:00 +0000
361+++ ubuntuone/platform/ipc/darwin.py 2012-05-17 12:59:18 +0000
362@@ -0,0 +1,44 @@
363+# -*- coding: utf-8 -*-
364+#
365+# Copyright 2012 Canonical Ltd.
366+#
367+# This program is free software: you can redistribute it and/or modify it
368+# under the terms of the GNU General Public License version 3, as published
369+# by the Free Software Foundation.
370+#
371+# This program is distributed in the hope that it will be useful, but
372+# WITHOUT ANY WARRANTY; without even the implied warranties of
373+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
374+# PURPOSE. See the GNU General Public License for more details.
375+#
376+# You should have received a copy of the GNU General Public License along
377+# with this program. If not, see <http://www.gnu.org/licenses/>.
378+#
379+# In addition, as a special exception, the copyright holders give
380+# permission to link the code of portions of this program with the
381+# OpenSSL library under certain conditions as described in each
382+# individual source file, and distribute linked combinations
383+# including the two.
384+# You must obey the GNU General Public License in all respects
385+# for all of the code used other than OpenSSL. If you modify
386+# file(s) with this exception, you may extend this exception to your
387+# version of the file(s), but you are not obligated to do so. If you
388+# do not wish to do so, delete this exception statement from your
389+# version. If you delete this exception statement from all source
390+# files in the program, then also delete it here.
391+"""IPC implementation for MAC OS."""
392+
393+import logging
394+
395+# Disable the "Invalid Name" check here, as we have lots of DBus style names
396+# pylint: disable-msg=C0103
397+
398+logger = logging.getLogger("ubuntuone.SyncDaemon.DBus")
399+
400+
401+def is_already_running(bus=None):
402+ """Return if the sd is running by trying to get the port."""
403+
404+
405+class IPCInterface(object):
406+ """Holder of all exposed objects."""
407
408=== modified file 'ubuntuone/platform/logger/__init__.py'
409--- ubuntuone/platform/logger/__init__.py 2012-05-14 19:04:43 +0000
410+++ ubuntuone/platform/logger/__init__.py 2012-05-17 12:59:18 +0000
411@@ -34,6 +34,9 @@
412 if sys.platform == "win32":
413 from ubuntuone.platform.logger import windows
414 source = windows
415+elif sys.platform == "darwin":
416+ from ubuntuone.platform.logger import darwin
417+ source = darwin
418 else:
419 from ubuntuone.platform.logger import linux
420 source = linux
421
422=== added file 'ubuntuone/platform/logger/darwin.py'
423--- ubuntuone/platform/logger/darwin.py 1970-01-01 00:00:00 +0000
424+++ ubuntuone/platform/logger/darwin.py 2012-05-17 12:59:18 +0000
425@@ -0,0 +1,37 @@
426+# -*- coding: utf-8 *-*
427+#
428+# Copyright 2012 Canonical Ltd.
429+#
430+# This program is free software: you can redistribute it and/or modify it
431+# under the terms of the GNU General Public License version 3, as published
432+# by the Free Software Foundation.
433+#
434+# This program is distributed in the hope that it will be useful, but
435+# WITHOUT ANY WARRANTY; without even the implied warranties of
436+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
437+# PURPOSE. See the GNU General Public License for more details.
438+#
439+# You should have received a copy of the GNU General Public License along
440+# with this program. If not, see <http://www.gnu.org/licenses/>.
441+#
442+# In addition, as a special exception, the copyright holders give
443+# permission to link the code of portions of this program with the
444+# OpenSSL library under certain conditions as described in each
445+# individual source file, and distribute linked combinations
446+# including the two.
447+# You must obey the GNU General Public License in all respects
448+# for all of the code used other than OpenSSL. If you modify
449+# file(s) with this exception, you may extend this exception to your
450+# version of the file(s), but you are not obligated to do so. If you
451+# do not wish to do so, delete this exception statement from your
452+# version. If you delete this exception statement from all source
453+# files in the program, then also delete it here.
454+
455+
456+def get_filesystem_logger():
457+ """Return the logger used in the filesystem."""
458+
459+
460+def setup_filesystem_logging(logging_class, root_handler):
461+ """Set the syncdameon extra loggin for MAC OS."""
462+ # there is nothing yet to be done here.
463
464=== modified file 'ubuntuone/platform/os_helper/__init__.py'
465--- ubuntuone/platform/os_helper/__init__.py 2012-04-27 20:38:13 +0000
466+++ ubuntuone/platform/os_helper/__init__.py 2012-05-17 12:59:18 +0000
467@@ -34,6 +34,9 @@
468 if sys.platform == "win32":
469 from ubuntuone.platform.os_helper import windows
470 source = windows
471+elif sys.platform == "darwin":
472+ from ubuntuone.platform.os_helper import darwin
473+ source = darwin
474 else:
475 from ubuntuone.platform.os_helper import linux
476 source = linux
477
478=== added file 'ubuntuone/platform/os_helper/darwin.py'
479--- ubuntuone/platform/os_helper/darwin.py 1970-01-01 00:00:00 +0000
480+++ ubuntuone/platform/os_helper/darwin.py 2012-05-17 12:59:18 +0000
481@@ -0,0 +1,110 @@
482+# ubuntuone.platform.os_helper - darwin platform imports
483+#
484+# Copyright 2012 Canonical Ltd.
485+#
486+# This program is free software: you can redistribute it and/or modify it
487+# under the terms of the GNU General Public License version 3, as published
488+# by the Free Software Foundation.
489+#
490+# This program is distributed in the hope that it will be useful, but
491+# WITHOUT ANY WARRANTY; without even the implied warranties of
492+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
493+# PURPOSE. See the GNU General Public License for more details.
494+#
495+# You should have received a copy of the GNU General Public License along
496+# with this program. If not, see <http://www.gnu.org/licenses/>.
497+#
498+# In addition, as a special exception, the copyright holders give
499+# permission to link the code of portions of this program with the
500+# OpenSSL library under certain conditions as described in each
501+# individual source file, and distribute linked combinations
502+# including the two.
503+# You must obey the GNU General Public License in all respects
504+# for all of the code used other than OpenSSL. If you modify
505+# file(s) with this exception, you may extend this exception to your
506+# version of the file(s), but you are not obligated to do so. If you
507+# do not wish to do so, delete this exception statement from your
508+# version. If you delete this exception statement from all source
509+# files in the program, then also delete it here.
510+"""
511+Darwin import for ubuntuone-client
512+
513+This module has to have all darwin specific modules and provide the api required
514+to support the darwin platform.
515+"""
516+
517+import errno
518+import logging
519+import os
520+import shutil
521+
522+from ubuntuone.platform.os_helper import unix
523+
524+platform = "darwin"
525+
526+logger = logging.getLogger('ubuntuone.SyncDaemon')
527+
528+
529+set_no_rights = unix.set_no_rights
530+set_file_readonly = unix.set_file_readonly
531+set_file_readwrite = unix.set_file_readwrite
532+set_dir_readonly = unix.set_dir_readonly
533+set_dir_readwrite = unix.set_dir_readwrite
534+allow_writes = unix.allow_writes
535+remove_file = unix.remove_file
536+remove_tree = unix.remove_tree
537+remove_dir = unix.remove_dir
538+path_exists = unix.path_exists
539+make_dir = unix.make_dir
540+open_file = unix.open_file
541+rename = unix.rename
542+native_rename = unix.native_rename
543+recursive_move = unix.recursive_move
544+make_link = unix.make_link
545+read_link = unix.read_link
546+is_link = unix.is_link
547+remove_link = unix.remove_link
548+listdir = unix.listdir
549+walk = unix.walk
550+access = unix.access
551+can_write = unix.can_write
552+stat_path = unix.stat_path
553+is_root = unix.is_root
554+get_path_list = unix.get_path_list
555+normpath = unix.normpath
556+
557+
558+def move_to_trash(path):
559+ """Move the file or dir to trash.
560+
561+ If had any error, or the system can't do it, just remove it.
562+
563+ Handles the case where path lies on a removable volume.
564+ """
565+ full_path = os.path.abspath(path)
566+
567+ if not path_exists(full_path):
568+ raise OSError(errno.ENOENT, 'File could %r not be found.' % full_path)
569+ if full_path.startswith("/Volumes/"):
570+ components = full_path.split(os.path.sep)
571+ vol_components = components[:3]
572+ file_components = [".Trashes", str(os.geteuid()),
573+ os.path.basename(full_path)]
574+ trashpath = os.path.sep.join(vol_components + file_components)
575+ else:
576+ trashpath = os.path.expanduser("~/.Trash")
577+
578+ try:
579+ shutil.move(path, trashpath)
580+ except Exception, reason:
581+ logger.warning("Problems moving to trash! (%r) Removing anyway: %r",
582+ reason, path)
583+ if os.path.isdir(path):
584+ shutil.rmtree(path)
585+ else:
586+ os.remove(path)
587+
588+
589+def set_application_name(app_name):
590+ """Set the name of the application."""
591+ raise Exception("This is not the way to do it on OS X")
592
593=== modified file 'ubuntuone/platform/os_helper/linux.py'
594--- ubuntuone/platform/os_helper/linux.py 2012-04-27 20:38:13 +0000
595+++ ubuntuone/platform/os_helper/linux.py 2012-05-17 12:59:18 +0000
596@@ -39,7 +39,6 @@
597 import logging
598 import os
599 import shutil
600-import stat
601 import sys
602
603 if 'gobject' in sys.modules and sys.modules['gobject'] is not None:
604@@ -49,140 +48,13 @@
605 from gi.repository import Gio, GLib
606 has_gi = True
607
608-from contextlib import contextmanager
609+from ubuntuone.platform.os_helper import unix
610
611 platform = "linux2"
612
613 logger = logging.getLogger('ubuntuone.SyncDaemon')
614
615
616-def set_no_rights(path):
617- """Remove all rights from the file."""
618- os.chmod(path, 0o000)
619-
620-
621-def set_file_readonly(path):
622- """Change path permissions to readonly in a file."""
623- os.chmod(path, 0444)
624-
625-
626-def set_file_readwrite(path):
627- """Change path permissions to readwrite in a file."""
628- os.chmod(path, 0664)
629-
630-
631-def set_dir_readonly(path):
632- """Change path permissions to readonly in a dir."""
633- os.chmod(path, 0555)
634-
635-
636-def set_dir_readwrite(path):
637- """Change path permissions to readwrite in a dir."""
638- os.chmod(path, 0775)
639-
640-
641-@contextmanager
642-def allow_writes(path):
643- """A very simple context manager to allow writting in RO dirs."""
644- prev_mod = stat.S_IMODE(os.stat(path).st_mode)
645- os.chmod(path, 0755)
646- yield
647- os.chmod(path, prev_mod)
648-
649-
650-def remove_file(path):
651- """Remove a file."""
652- os.remove(path)
653-
654-
655-def remove_tree(path):
656- """Remove a dir and all its children."""
657- shutil.rmtree(path)
658-
659-
660-def remove_dir(path):
661- """Remove a dir."""
662- os.rmdir(path)
663-
664-
665-def path_exists(path):
666- """Return if the path exists."""
667- return os.path.exists(path)
668-
669-
670-def make_dir(path, recursive=False):
671- """Make a dir, optionally creating all the middle ones."""
672- if recursive:
673- os.makedirs(path)
674- else:
675- os.mkdir(path)
676-
677-
678-def open_file(path, mode='r'):
679- """Open a file."""
680- return open(path, mode)
681-
682-
683-def rename(path_from, path_to):
684- """Rename a file or directory."""
685- os.rename(path_from, path_to)
686-
687-
688-def native_rename(path_from, path_to):
689- """Rename a file or directory."""
690- os.rename(path_from, path_to)
691-
692-
693-def recursive_move(path_from, path_to):
694- """Perform a recursive move."""
695- shutil.move(path_from, path_to)
696-
697-
698-def make_link(target, destination):
699- """Create a link from the destination to the target."""
700- os.symlink(target, destination)
701-
702-
703-def read_link(path):
704- """Read the destination of a link."""
705- return os.readlink(path)
706-
707-
708-def is_link(path):
709- """Returns if a path is a link or not."""
710- return os.path.islink(path)
711-
712-
713-def remove_link(path):
714- """Removes a link."""
715- if is_link(path):
716- os.unlink(path)
717-
718-
719-def listdir(directory):
720- """List a directory."""
721- return os.listdir(directory)
722-
723-
724-def walk(path, topdown=True):
725- return os.walk(path, topdown)
726-
727-
728-def access(path):
729- """Return if the path is at least readable."""
730- return os.access(path, os.R_OK)
731-
732-
733-def can_write(path):
734- """Return if the path can be written to."""
735- return os.access(path, os.W_OK)
736-
737-
738-def stat_path(path):
739- """Return stat info about a path."""
740- return os.lstat(path)
741-
742-
743 def move_to_trash(path):
744 """Move the file or dir to trash.
745
746@@ -224,16 +96,30 @@
747 gobject.set_application_name(app_name)
748
749
750-def is_root():
751- """Return if the user is running as root."""
752- return not os.geteuid()
753-
754-
755-def get_path_list(path):
756- """Return a list with the diff components of the path."""
757- return os.path.abspath(path).split(os.path.sep)
758-
759-
760-def normpath(path):
761- """Normalize path, eliminating double slashes, etc."""
762- return os.path.normpath(path)
763+set_no_rights = unix.set_no_rights
764+set_file_readonly = unix.set_file_readonly
765+set_file_readwrite = unix.set_file_readwrite
766+set_dir_readonly = unix.set_dir_readonly
767+set_dir_readwrite = unix.set_dir_readwrite
768+allow_writes = unix.allow_writes
769+remove_file = unix.remove_file
770+remove_tree = unix.remove_tree
771+remove_dir = unix.remove_dir
772+path_exists = unix.path_exists
773+make_dir = unix.make_dir
774+open_file = unix.open_file
775+rename = unix.rename
776+native_rename = unix.native_rename
777+recursive_move = unix.recursive_move
778+make_link = unix.make_link
779+read_link = unix.read_link
780+is_link = unix.is_link
781+remove_link = unix.remove_link
782+listdir = unix.listdir
783+walk = unix.walk
784+access = unix.access
785+can_write = unix.can_write
786+stat_path = unix.stat_path
787+is_root = unix.is_root
788+get_path_list = unix.get_path_list
789+normpath = unix.normpath
790
791=== added file 'ubuntuone/platform/os_helper/unix.py'
792--- ubuntuone/platform/os_helper/unix.py 1970-01-01 00:00:00 +0000
793+++ ubuntuone/platform/os_helper/unix.py 2012-05-17 12:59:18 +0000
794@@ -0,0 +1,186 @@
795+# -*- encoding: utf-8 -*-
796+#
797+# Copyright 2012 Canonical Ltd.
798+#
799+# This program is free software: you can redistribute it and/or modify it
800+# under the terms of the GNU General Public License version 3, as published
801+# by the Free Software Foundation.
802+#
803+# This program is distributed in the hope that it will be useful, but
804+# WITHOUT ANY WARRANTY; without even the implied warranties of
805+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
806+# PURPOSE. See the GNU General Public License for more details.
807+#
808+# You should have received a copy of the GNU General Public License along
809+# with this program. If not, see <http://www.gnu.org/licenses/>.
810+#
811+# In addition, as a special exception, the copyright holders give
812+# permission to link the code of portions of this program with the
813+# OpenSSL library under certain conditions as described in each
814+# individual source file, and distribute linked combinations
815+# including the two.
816+# You must obey the GNU General Public License in all respects
817+# for all of the code used other than OpenSSL. If you modify
818+# file(s) with this exception, you may extend this exception to your
819+# version of the file(s), but you are not obligated to do so. If you
820+# do not wish to do so, delete this exception statement from your
821+# version. If you delete this exception statement from all source
822+# files in the program, then also delete it here.
823+"""
824+Unix import for ubuntuone-client
825+
826+This module has to have all unix specific modules and provide the api required
827+to support unix-like platform.
828+"""
829+
830+import logging
831+import os
832+import shutil
833+import stat
834+
835+from contextlib import contextmanager
836+
837+
838+logger = logging.getLogger('ubuntuone.SyncDaemon')
839+
840+
841+def set_no_rights(path):
842+ """Remove all rights from the file."""
843+ os.chmod(path, 0o000)
844+
845+
846+def set_file_readonly(path):
847+ """Change path permissions to readonly in a file."""
848+ os.chmod(path, 0444)
849+
850+
851+def set_file_readwrite(path):
852+ """Change path permissions to readwrite in a file."""
853+ os.chmod(path, 0664)
854+
855+
856+def set_dir_readonly(path):
857+ """Change path permissions to readonly in a dir."""
858+ os.chmod(path, 0555)
859+
860+
861+def set_dir_readwrite(path):
862+ """Change path permissions to readwrite in a dir."""
863+ os.chmod(path, 0775)
864+
865+
866+@contextmanager
867+def allow_writes(path):
868+ """A very simple context manager to allow writting in RO dirs."""
869+ prev_mod = stat.S_IMODE(os.stat(path).st_mode)
870+ os.chmod(path, 0755)
871+ yield
872+ os.chmod(path, prev_mod)
873+
874+
875+def remove_file(path):
876+ """Remove a file."""
877+ os.remove(path)
878+
879+
880+def remove_tree(path):
881+ """Remove a dir and all its children."""
882+ shutil.rmtree(path)
883+
884+
885+def remove_dir(path):
886+ """Remove a dir."""
887+ os.rmdir(path)
888+
889+
890+def path_exists(path):
891+ """Return if the path exists."""
892+ return os.path.exists(path)
893+
894+
895+def make_dir(path, recursive=False):
896+ """Make a dir, optionally creating all the middle ones."""
897+ if recursive:
898+ os.makedirs(path)
899+ else:
900+ os.mkdir(path)
901+
902+
903+def open_file(path, mode='r'):
904+ """Open a file."""
905+ return open(path, mode)
906+
907+
908+def rename(path_from, path_to):
909+ """Rename a file or directory."""
910+ os.rename(path_from, path_to)
911+
912+
913+def native_rename(path_from, path_to):
914+ """Rename a file or directory."""
915+ os.rename(path_from, path_to)
916+
917+
918+def recursive_move(path_from, path_to):
919+ """Perform a recursive move."""
920+ shutil.move(path_from, path_to)
921+
922+
923+def make_link(target, destination):
924+ """Create a link from the destination to the target."""
925+ os.symlink(target, destination)
926+
927+
928+def read_link(path):
929+ """Read the destination of a link."""
930+ return os.readlink(path)
931+
932+
933+def is_link(path):
934+ """Returns if a path is a link or not."""
935+ return os.path.islink(path)
936+
937+
938+def remove_link(path):
939+ """Removes a link."""
940+ if is_link(path):
941+ os.unlink(path)
942+
943+
944+def listdir(directory):
945+ """List a directory."""
946+ return os.listdir(directory)
947+
948+
949+def walk(path, topdown=True):
950+ return os.walk(path, topdown)
951+
952+
953+def access(path):
954+ """Return if the path is at least readable."""
955+ return os.access(path, os.R_OK)
956+
957+
958+def can_write(path):
959+ """Return if the path can be written to."""
960+ return os.access(path, os.W_OK)
961+
962+
963+def stat_path(path):
964+ """Return stat info about a path."""
965+ return os.lstat(path)
966+
967+
968+def is_root():
969+ """Return if the user is running as root."""
970+ return not os.geteuid()
971+
972+
973+def get_path_list(path):
974+ """Return a list with the diff components of the path."""
975+ return os.path.abspath(path).split(os.path.sep)
976+
977+
978+def normpath(path):
979+ """Normalize path, eliminating double slashes, etc."""
980+ return os.path.normpath(path)
981
982=== modified file 'ubuntuone/platform/session/__init__.py'
983--- ubuntuone/platform/session/__init__.py 2012-04-27 19:30:11 +0000
984+++ ubuntuone/platform/session/__init__.py 2012-05-17 12:59:18 +0000
985@@ -41,6 +41,9 @@
986 if sys.platform == "win32":
987 from ubuntuone.platform.session import windows
988 source = windows
989+elif sys.platform == "darwin":
990+ from ubuntuone.platform.session import darwin
991+ source = darwin
992 else:
993 from ubuntuone.platform.session import linux
994 source = linux
995
996=== added file 'ubuntuone/platform/session/darwin.py'
997--- ubuntuone/platform/session/darwin.py 1970-01-01 00:00:00 +0000
998+++ ubuntuone/platform/session/darwin.py 2012-05-17 12:59:18 +0000
999@@ -0,0 +1,43 @@
1000+# -*- coding: utf-8 *-*
1001+#
1002+# Copyright 2012 Canonical Ltd.
1003+#
1004+# This program is free software: you can redistribute it and/or modify it
1005+# under the terms of the GNU General Public License version 3, as published
1006+# by the Free Software Foundation.
1007+#
1008+# This program is distributed in the hope that it will be useful, but
1009+# WITHOUT ANY WARRANTY; without even the implied warranties of
1010+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1011+# PURPOSE. See the GNU General Public License for more details.
1012+#
1013+# You should have received a copy of the GNU General Public License along
1014+# with this program. If not, see <http://www.gnu.org/licenses/>.
1015+#
1016+# In addition, as a special exception, the copyright holders give
1017+# permission to link the code of portions of this program with the
1018+# OpenSSL library under certain conditions as described in each
1019+# individual source file, and distribute linked combinations
1020+# including the two.
1021+# You must obey the GNU General Public License in all respects
1022+# for all of the code used other than OpenSSL. If you modify
1023+# file(s) with this exception, you may extend this exception to your
1024+# version of the file(s), but you are not obligated to do so. If you
1025+# do not wish to do so, delete this exception statement from your
1026+# version. If you delete this exception statement from all source
1027+# files in the program, then also delete it here.
1028+"""Inhibit session logout when busy."""
1029+
1030+from twisted.internet import defer
1031+
1032+
1033+class Inhibitor(object):
1034+ """An object representing an inhibition, that can be cancelled."""
1035+
1036+ def inhibit(self, flags, reason):
1037+ """Inhibit some events with a given reason."""
1038+ return defer.succeed(None)
1039+
1040+ def cancel(self):
1041+ """Cancel the inhibition for the current cookie."""
1042+ return defer.succeed(None)
1043
1044=== modified file 'ubuntuone/platform/tools/__init__.py'
1045--- ubuntuone/platform/tools/__init__.py 2012-04-09 20:07:05 +0000
1046+++ ubuntuone/platform/tools/__init__.py 2012-05-17 12:59:18 +0000
1047@@ -39,6 +39,9 @@
1048 if sys.platform == 'win32':
1049 from ubuntuone.platform.tools import windows
1050 source = windows
1051+elif sys.platform == 'darwin':
1052+ from ubuntuone.platform.tools import darwin
1053+ source = darwin
1054 else:
1055 from ubuntuone.platform.tools import linux
1056 source = linux
1057
1058=== added file 'ubuntuone/platform/tools/darwin.py'
1059--- ubuntuone/platform/tools/darwin.py 1970-01-01 00:00:00 +0000
1060+++ ubuntuone/platform/tools/darwin.py 2012-05-17 12:59:18 +0000
1061@@ -0,0 +1,47 @@
1062+# -*- coding: utf-8 -*-
1063+#
1064+# Copyright 2012 Canonical Ltd.
1065+#
1066+# This program is free software: you can redistribute it and/or modify it
1067+# under the terms of the GNU General Public License version 3, as published
1068+# by the Free Software Foundation.
1069+#
1070+# This program is distributed in the hope that it will be useful, but
1071+# WITHOUT ANY WARRANTY; without even the implied warranties of
1072+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1073+# PURPOSE. See the GNU General Public License for more details.
1074+#
1075+# You should have received a copy of the GNU General Public License along
1076+# with this program. If not, see <http://www.gnu.org/licenses/>.
1077+#
1078+# In addition, as a special exception, the copyright holders give
1079+# permission to link the code of portions of this program with the
1080+# OpenSSL library under certain conditions as described in each
1081+# individual source file, and distribute linked combinations
1082+# including the two.
1083+# You must obey the GNU General Public License in all respects
1084+# for all of the code used other than OpenSSL. If you modify
1085+# file(s) with this exception, you may extend this exception to your
1086+# version of the file(s), but you are not obligated to do so. If you
1087+# do not wish to do so, delete this exception statement from your
1088+# version. If you delete this exception statement from all source
1089+# files in the program, then also delete it here.
1090+"""SyncDaemon Tools."""
1091+
1092+
1093+def is_already_running(*arg):
1094+ """Empty implementation for MAC OS"""
1095+
1096+
1097+class IPCError(object):
1098+ """Empty implementation for MAC OS"""
1099+
1100+ def __init__(self, *args):
1101+ """Empty implementation for MAC OS"""
1102+
1103+
1104+class SyncDaemonToolProxy(object):
1105+ """Empty implementation for MAC OS"""
1106+
1107+ def __init__(self, *args):
1108+ """Empty implementation for MAC OS"""

Subscribers

People subscribed via source and target branches