Merge lp:~nataliabidart/ubuntuone-client/xdg-return-bytes into lp:ubuntuone-client
- xdg-return-bytes
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Natalia Bidart | ||||
Approved revision: | 1082 | ||||
Merged at revision: | 1080 | ||||
Proposed branch: | lp:~nataliabidart/ubuntuone-client/xdg-return-bytes | ||||
Merge into: | lp:ubuntuone-client | ||||
Diff against target: |
446 lines (+127/-88) 11 files modified
bin/ubuntuone-syncdaemon (+26/-13) tests/platform/test_xdg_base_directory.py (+10/-0) tests/platform/windows/test_xdg_base_directory.py (+5/-6) tests/syncdaemon/test_config.py (+49/-33) ubuntuone/platform/linux/__init__.py (+1/-1) ubuntuone/platform/linux/os_helper.py (+1/-6) ubuntuone/platform/windows/__init__.py (+0/-1) ubuntuone/platform/windows/os_helper.py (+0/-6) ubuntuone/platform/xdg_base_directory/windows.py (+4/-3) ubuntuone/syncdaemon/config.py (+28/-16) ubuntuone/syncdaemon/main.py (+3/-3) |
||||
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-client/xdg-return-bytes | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alejandro J. Cura (community) | Approve | ||
Guillermo Gonzalez | Approve | ||
Review via email: mp+69808@code.launchpad.net |
Commit message
- XDG data dirs must return bytes (LP: #818030).
Description of the change
To post a comment you must log in.
- 1080. By Natalia Bidart
-
Typo!
Revision history for this message
Alejandro J. Cura (alecu) wrote : | # |
Waiting for a few style changes, but basically "Approved!!!!!"
review:
Approve
- 1081. By Natalia Bidart
-
Merged trunk in.
- 1082. By Natalia Bidart
-
Style fixes.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/ubuntuone-syncdaemon' |
2 | --- bin/ubuntuone-syncdaemon 2011-07-28 14:36:35 +0000 |
3 | +++ bin/ubuntuone-syncdaemon 2011-07-29 19:11:49 +0000 |
4 | @@ -37,7 +37,15 @@ |
5 | import sys |
6 | import shutil |
7 | |
8 | -from ubuntuone.platform import is_already_running, set_application_name, is_root |
9 | +from ubuntuone.platform import ( |
10 | + can_write, |
11 | + set_dir_readwrite, |
12 | + is_already_running, |
13 | + is_root, |
14 | + make_dir, |
15 | + path_exists, |
16 | + set_application_name, |
17 | +) |
18 | from ubuntuone.syncdaemon import logger, config |
19 | from ubuntuone.syncdaemon.config import ( |
20 | get_config_files, |
21 | @@ -127,31 +135,36 @@ |
22 | |
23 | # check if we are using xdg_data_home and it doesn't exists |
24 | if xdg_data_home in options.data_dir and \ |
25 | - not os.path.exists(options.data_dir): |
26 | + not path_exists(options.data_dir): |
27 | # if we have metadata in the old xdg_cache, move it! |
28 | old_data_dir = options.data_dir.replace(xdg_data_home, xdg_cache_home) |
29 | - if os.path.exists(old_data_dir): |
30 | + if path_exists(old_data_dir): |
31 | parent = os.path.dirname(options.data_dir) |
32 | - if os.path.exists(parent) and not os.access(parent, os.W_OK): |
33 | + if path_exists(parent) and not can_write(parent): |
34 | # make the parent dir writable |
35 | - os.chmod(parent, 0775) |
36 | - elif not os.path.exists(parent): |
37 | + set_dir_readwrite(parent) |
38 | + elif not path_exists(parent): |
39 | # if it don't exits |
40 | - os.makedirs(parent) |
41 | + make_dir(parent, recursive=True) |
42 | shutil.move(old_data_dir, options.data_dir) |
43 | - if not os.path.exists(options.data_dir): |
44 | + if not path_exists(options.data_dir): |
45 | parent = os.path.dirname(options.data_dir) |
46 | - if os.path.exists(parent) and not os.access(parent, os.W_OK): |
47 | + if path_exists(parent) and not can_write(parent): |
48 | # make the parent dir writable |
49 | - os.chmod(parent, 0775) |
50 | - os.makedirs(options.data_dir) |
51 | + set_dir_readwrite(parent) |
52 | + make_dir(options.data_dir, recursive=True) |
53 | |
54 | # create the partials_dir |
55 | partials_dir = os.path.join(xdg_cache_home, 'ubuntuone', 'partials') |
56 | - if not os.path.exists(partials_dir): |
57 | - os.makedirs(partials_dir) |
58 | + if not path_exists(partials_dir): |
59 | + make_dir(partials_dir, recursive=True) |
60 | |
61 | logger.rotate_logs() |
62 | + |
63 | + assert isinstance(options.root_dir, str) |
64 | + assert isinstance(options.shares_dir, str) |
65 | + assert isinstance(options.data_dir, str) |
66 | + |
67 | main = Main(options.root_dir, options.shares_dir, options.data_dir, |
68 | partials_dir, host=options.host, port=int(options.port), |
69 | dns_srv=options.dns_srv, ssl=True, |
70 | |
71 | === modified file 'tests/platform/test_xdg_base_directory.py' |
72 | --- tests/platform/test_xdg_base_directory.py 2011-07-26 16:07:08 +0000 |
73 | +++ tests/platform/test_xdg_base_directory.py 2011-07-29 19:11:49 +0000 |
74 | @@ -34,3 +34,13 @@ |
75 | 'ubuntuone', 'log') |
76 | self.assertEqual(expected, xdg_base_directory.ubuntuone_log_dir) |
77 | self.assertTrue(os.path.exists(expected)) |
78 | + |
79 | + def test_xdg_cache_home_is_bytes(self): |
80 | + """The returned path is bytes.""" |
81 | + actual = xdg_base_directory.xdg_cache_home |
82 | + self.assertIsInstance(actual, str) |
83 | + |
84 | + def test_xdg_data_home_is_bytes(self): |
85 | + """The returned path is bytes.""" |
86 | + actual = xdg_base_directory.xdg_data_home |
87 | + self.assertIsInstance(actual, str) |
88 | |
89 | === modified file 'tests/platform/windows/test_xdg_base_directory.py' |
90 | --- tests/platform/windows/test_xdg_base_directory.py 2011-07-28 12:51:07 +0000 |
91 | +++ tests/platform/windows/test_xdg_base_directory.py 2011-07-29 19:11:49 +0000 |
92 | @@ -17,12 +17,11 @@ |
93 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
94 | """Platform independent tests for the credentials management.""" |
95 | |
96 | -import os |
97 | - |
98 | import win32com.shell |
99 | |
100 | from twisted.trial.unittest import TestCase |
101 | |
102 | +from ubuntuone.platform.windows.os_helper import assert_syncdaemon_path |
103 | from ubuntuone.platform.xdg_base_directory.windows import get_special_folders |
104 | |
105 | |
106 | @@ -38,8 +37,8 @@ |
107 | def __init__(self): |
108 | """Set the proper mapping between CSIDL_ consts.""" |
109 | self.values = { |
110 | - 0: r'c:\path\to\users\home', |
111 | - 1: r'c:\path\to\users\home\appData\local'} |
112 | + 0: u'c:\\path\\to\\users\\home', |
113 | + 1: u'c:\\path\\to\\users\\home\\appData\\local'} |
114 | |
115 | def SHGetFolderPath(self, dummy0, shellconValue, dummy2, dummy3): |
116 | """Override SHGetFolderPath functionality.""" |
117 | @@ -67,5 +66,5 @@ |
118 | self.assertTrue(special_folders['Local AppData'].startswith( |
119 | special_folders['AppData'])) |
120 | |
121 | - for k in special_folders: |
122 | - os.access(special_folders[k], os.W_OK) |
123 | + for val in special_folders.itervalues(): |
124 | + assert_syncdaemon_path(val) |
125 | |
126 | === modified file 'tests/syncdaemon/test_config.py' |
127 | --- tests/syncdaemon/test_config.py 2011-07-27 13:27:22 +0000 |
128 | +++ tests/syncdaemon/test_config.py 2011-07-29 19:11:49 +0000 |
129 | @@ -471,7 +471,7 @@ |
130 | |
131 | |
132 | class ConfigglueParsersTests(BaseTwistedTestCase): |
133 | - """Tests for our custom configglue parsers""" |
134 | + """Tests for our custom configglue parsers.""" |
135 | |
136 | def test_throttling_limit_parser(self): |
137 | """Test throttling_limit_parser""" |
138 | @@ -497,39 +497,55 @@ |
139 | self.assertEqual(logging.DEBUG, parser(bad_value)) |
140 | self.assertEqual(logging.DEBUG, parser(invalid_value)) |
141 | |
142 | - def test_home_dir_parser(self): |
143 | - """Test home_dir_parser""" |
144 | - good_value = '~/hola' |
145 | - bad_value = 'hola' |
146 | - invalid_value = None |
147 | - parser = config.home_dir_parser |
148 | - homedir = os.path.join('/', 'home', 'fake') |
149 | + |
150 | +class XdgHomeParsersTests(BaseTwistedTestCase): |
151 | + """Tests for our custom xdg parsers.""" |
152 | + |
153 | + good_value = '~/hola/mundo' |
154 | + name = 'home' |
155 | + xdg_dir = os.path.join('', 'home', 'fake') |
156 | + |
157 | + @defer.inlineCallbacks |
158 | + def setUp(self): |
159 | + yield super(XdgHomeParsersTests, self).setUp() |
160 | + self.parser = getattr(config, '%s_dir_parser' % self.name) |
161 | + |
162 | + def test_good_value(self): |
163 | + """Test the parser using a good value.""" |
164 | + homedir = os.path.join('', 'home', 'fake') |
165 | with environ('HOME', homedir): |
166 | - self.assertEqual(os.path.join(homedir, 'hola'), parser(good_value)) |
167 | - self.assertEqual('hola', parser(bad_value)) |
168 | - self.assertRaises(AttributeError, parser, invalid_value) |
169 | - |
170 | - def test_xdg_cache_dir_parser(self): |
171 | - """Test xdg_cache_dir_parser""" |
172 | - good_value = 'hola' |
173 | - bad_value = '/hola' |
174 | - invalid_value = None |
175 | - parser = config.xdg_cache_dir_parser |
176 | - self.assertEquals(os.path.join(xdg_cache_home, 'hola'), |
177 | - parser(good_value)) |
178 | - self.assertEquals('/hola', parser(bad_value)) |
179 | - self.assertRaises(AttributeError, parser, invalid_value) |
180 | - |
181 | - def test_xdg_data_dir_parser(self): |
182 | - """Test xdg_data_dir_parser""" |
183 | - good_value = 'hola' |
184 | - bad_value = '/hola' |
185 | - invalid_value = None |
186 | - parser = config.xdg_data_dir_parser |
187 | - self.assertEquals(os.path.join(xdg_data_home, 'hola'), |
188 | - parser(good_value)) |
189 | - self.assertEquals('/hola', parser(bad_value)) |
190 | - self.assertRaises(AttributeError, parser, invalid_value) |
191 | + expected = os.path.join(self.xdg_dir, 'hola', 'mundo') |
192 | + actual = self.parser(self.good_value) |
193 | + self.assertEqual(expected, actual) |
194 | + self.assertIsInstance(actual, str) |
195 | + self.assertNotIsInstance(actual, unicode) |
196 | + |
197 | + def test_bad_value(self): |
198 | + """Test the parser using a bad value.""" |
199 | + bad_value = '/hola' |
200 | + self.assertEqual(config.path_from_unix(bad_value), |
201 | + self.parser(bad_value)) |
202 | + |
203 | + def test_invalid_value(self): |
204 | + """Test the parser using an invalid value.""" |
205 | + invalid_value = None |
206 | + self.assertRaises(AttributeError, self.parser, invalid_value) |
207 | + |
208 | + |
209 | +class XdgCacheParsersTests(XdgHomeParsersTests): |
210 | + """Tests for our custom xdg parsers.""" |
211 | + |
212 | + good_value = 'hola/mundo' |
213 | + name = 'xdg_cache' |
214 | + xdg_dir = xdg_cache_home |
215 | + |
216 | + |
217 | +class XdgDataParsersTests(XdgCacheParsersTests): |
218 | + """Tests for our custom xdg parsers.""" |
219 | + |
220 | + good_value = 'hola/mundo' |
221 | + name = 'xdg_data' |
222 | + xdg_dir = xdg_data_home |
223 | |
224 | |
225 | class SyncDaemonConfigParserTests(BaseTwistedTestCase): |
226 | |
227 | === modified file 'ubuntuone/platform/linux/__init__.py' |
228 | --- ubuntuone/platform/linux/__init__.py 2011-07-28 17:32:56 +0000 |
229 | +++ ubuntuone/platform/linux/__init__.py 2011-07-29 19:11:49 +0000 |
230 | @@ -52,13 +52,13 @@ |
231 | set_file_readwrite, |
232 | set_no_rights, |
233 | stat_path, |
234 | - validate_path_from_unix, |
235 | ) |
236 | from ubuntuone.platform.linux.credentials import CredentialsManagementTool |
237 | from ubuntuone.platform.linux.logger import setup_filesystem_logging, get_filesystem_logger |
238 | from ubuntuone.platform.linux.filesystem_notifications import FilesystemMonitor |
239 | from ubuntuone.platform.linux.notification import Notification |
240 | |
241 | + |
242 | class ExternalInterface(object): |
243 | """An ExternalInterface implemented with a DBus interface.""" |
244 | |
245 | |
246 | === modified file 'ubuntuone/platform/linux/os_helper.py' |
247 | --- ubuntuone/platform/linux/os_helper.py 2011-07-19 21:59:27 +0000 |
248 | +++ ubuntuone/platform/linux/os_helper.py 2011-07-29 19:11:49 +0000 |
249 | @@ -154,12 +154,7 @@ |
250 | |
251 | def is_root(): |
252 | """Return if the user is running as root.""" |
253 | - return not os.geteuid() |
254 | - |
255 | - |
256 | -def validate_path_from_unix(path): |
257 | - """Get a unix path and return it so that it cna be used.""" |
258 | - return path |
259 | + return not os.geteuid() |
260 | |
261 | |
262 | def get_path_list(path): |
263 | |
264 | === modified file 'ubuntuone/platform/windows/__init__.py' |
265 | --- ubuntuone/platform/windows/__init__.py 2011-07-28 17:32:56 +0000 |
266 | +++ ubuntuone/platform/windows/__init__.py 2011-07-29 19:11:49 +0000 |
267 | @@ -51,7 +51,6 @@ |
268 | set_file_readwrite, |
269 | set_no_rights, |
270 | stat_path, |
271 | - validate_path_from_unix, |
272 | ) |
273 | from ubuntuone.platform.windows.credentials import CredentialsManagementTool |
274 | from ubuntuone.platform.windows import event_logging |
275 | |
276 | === modified file 'ubuntuone/platform/windows/os_helper.py' |
277 | --- ubuntuone/platform/windows/os_helper.py 2011-07-28 15:43:05 +0000 |
278 | +++ ubuntuone/platform/windows/os_helper.py 2011-07-29 19:11:49 +0000 |
279 | @@ -716,12 +716,6 @@ |
280 | return False |
281 | |
282 | |
283 | -def validate_path_from_unix(path): |
284 | - """Get a unix path and return it so that it can be used.""" |
285 | - path = path.replace('/', '\\') |
286 | - return path |
287 | - |
288 | - |
289 | @windowspath() |
290 | def get_path_list(path): |
291 | """Return a list with the diff components of the path.""" |
292 | |
293 | === modified file 'ubuntuone/platform/xdg_base_directory/windows.py' |
294 | --- ubuntuone/platform/xdg_base_directory/windows.py 2011-07-27 21:09:30 +0000 |
295 | +++ ubuntuone/platform/xdg_base_directory/windows.py 2011-07-29 19:11:49 +0000 |
296 | @@ -31,11 +31,12 @@ |
297 | # CSIDL_LOCAL_APPDATA = C:\Users\<username>\AppData\Local |
298 | # CSIDL_PROFILE = C:\Users\<username> |
299 | path = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, None, 0) |
300 | - special_folders['Personal'] = path |
301 | + special_folders['Personal'] = path.encode('utf8') |
302 | |
303 | path = shell.SHGetFolderPath(0, shellcon.CSIDL_LOCAL_APPDATA, None, 0) |
304 | - special_folders['Local AppData'] = path |
305 | - special_folders['AppData'] = os.path.dirname(path) |
306 | + special_folders['Local AppData'] = path.encode('utf8') |
307 | + path = os.path.dirname(path) |
308 | + special_folders['AppData'] = path.encode('utf8') |
309 | |
310 | return special_folders |
311 | |
312 | |
313 | === modified file 'ubuntuone/syncdaemon/config.py' |
314 | --- ubuntuone/syncdaemon/config.py 2011-07-28 15:43:05 +0000 |
315 | +++ ubuntuone/syncdaemon/config.py 2011-07-29 19:11:49 +0000 |
316 | @@ -25,6 +25,7 @@ |
317 | |
318 | from ConfigParser import NoOptionError, NoSectionError |
319 | from optparse import OptionParser |
320 | +from ubuntuone.platform import path_exists, rename |
321 | from ubuntuone.platform.xdg_base_directory import ( |
322 | load_config_paths, |
323 | save_config_path, |
324 | @@ -56,7 +57,6 @@ |
325 | TypedConfigParser = new_tcp |
326 | del new_tcp |
327 | # end of naming shenanigans |
328 | -from ubuntuone.platform import validate_path_from_unix |
329 | |
330 | CONFIG_FILE = 'syncdaemon.conf' |
331 | CONFIG_LOGS = 'logging.conf' |
332 | @@ -76,6 +76,8 @@ |
333 | # this object is the shared config |
334 | _user_config = None |
335 | |
336 | +path_from_unix = lambda path: path.replace('/', os.path.sep) |
337 | + |
338 | |
339 | def home_dir_parser(value): |
340 | """Parser for the root_dir and shares_dir options. |
341 | @@ -83,21 +85,31 @@ |
342 | Return the path using user home + value. |
343 | |
344 | """ |
345 | - return os.path.expanduser(validate_path_from_unix(value)) |
346 | + result = os.path.expanduser(path_from_unix(value)) |
347 | + assert isinstance(result, str) |
348 | + return result |
349 | |
350 | |
351 | def xdg_cache_dir_parser(value): |
352 | - """ Parser for the data_dir option. |
353 | - returns the path using xdg_cache_home + value. |
354 | + """Parser for the data_dir option. |
355 | + |
356 | + Return the path using xdg_cache_home + value. |
357 | + |
358 | """ |
359 | - return os.path.join(xdg_cache_home, validate_path_from_unix(value)) |
360 | + result = os.path.join(xdg_cache_home, path_from_unix(value)) |
361 | + assert isinstance(result, str) |
362 | + return result |
363 | |
364 | |
365 | def xdg_data_dir_parser(value): |
366 | - """ Parser for the data_dir option. |
367 | - returns the path using xdg_data_home + value. |
368 | + """Parser for the data_dir option. |
369 | + |
370 | + Return the path using xdg_data_home + value. |
371 | + |
372 | """ |
373 | - return os.path.join(xdg_data_home, validate_path_from_unix(value)) |
374 | + result = os.path.join(xdg_data_home, path_from_unix(value)) |
375 | + assert isinstance(result, str) |
376 | + return result |
377 | |
378 | |
379 | def log_level_parser(value): |
380 | @@ -140,11 +152,11 @@ |
381 | config_files = [] |
382 | for xdg_config_dir in load_config_paths('ubuntuone'): |
383 | config_file = os.path.join(xdg_config_dir, CONFIG_FILE) |
384 | - if os.path.exists(config_file): |
385 | + if path_exists(config_file): |
386 | config_files.append(config_file) |
387 | |
388 | config_logs = os.path.join(xdg_config_dir, CONFIG_LOGS) |
389 | - if os.path.exists(config_logs): |
390 | + if path_exists(config_logs): |
391 | config_files.append(config_logs) |
392 | |
393 | # reverse the list as load_config_paths returns the user dir first |
394 | @@ -152,11 +164,11 @@ |
395 | # if we are running from a branch, get the config files from it too |
396 | config_file = os.path.join(os.path.dirname(__file__), os.path.pardir, |
397 | os.path.pardir, 'data', CONFIG_FILE) |
398 | - if os.path.exists(config_file): |
399 | + if path_exists(config_file): |
400 | config_files.append(config_file) |
401 | |
402 | config_logs = os.path.join('data', CONFIG_LOGS) |
403 | - if os.path.exists(config_logs): |
404 | + if path_exists(config_logs): |
405 | config_files.append(config_logs) |
406 | |
407 | return config_files |
408 | @@ -279,11 +291,11 @@ |
409 | for section in [MAIN, THROTTLING, NOTIFICATIONS]: |
410 | if self.has_section(section) and not self.options(section): |
411 | self.remove_section(section) |
412 | - with open(self.config_file+'.new', 'w') as fp: |
413 | + with open(self.config_file + '.new', 'w') as fp: |
414 | self.write(fp) |
415 | - if os.path.exists(self.config_file): |
416 | - os.rename(self.config_file, self.config_file+'.old') |
417 | - os.rename(self.config_file+'.new', self.config_file) |
418 | + if path_exists(self.config_file): |
419 | + rename(self.config_file, self.config_file + '.old') |
420 | + rename(self.config_file + '.new', self.config_file) |
421 | |
422 | def get_parsed(self, section, option): |
423 | """get that fallbacks to our custom defaults""" |
424 | |
425 | === modified file 'ubuntuone/syncdaemon/main.py' |
426 | --- ubuntuone/syncdaemon/main.py 2011-06-23 13:10:19 +0000 |
427 | +++ ubuntuone/syncdaemon/main.py 2011-07-29 19:11:49 +0000 |
428 | @@ -98,6 +98,9 @@ |
429 | |
430 | self.logger.info("Starting Ubuntu One client version %s", |
431 | clientdefs.VERSION) |
432 | + self.logger.info("Using %r as root dir", self.root_dir) |
433 | + self.logger.info("Using %r as data dir", self.data_dir) |
434 | + self.logger.info("Using %r as shares root dir", self.shares_dir) |
435 | self.db = tritcask.Tritcask(self.tritcask_dir) |
436 | self.vm = volume_manager.VolumeManager(self) |
437 | self.fs = filesystem_manager.FileSystemManager( |
438 | @@ -135,9 +138,6 @@ |
439 | self.eventlog_listener = None |
440 | self.start_event_logger() |
441 | self.start_status_listener() |
442 | - self.logger.info("Using %r as root dir", self.root_dir) |
443 | - self.logger.info("Using %r as data dir", self.data_dir) |
444 | - self.logger.info("Using %r as shares root dir", self.shares_dir) |
445 | self.mark = task.LoopingCall(self.log_mark) |
446 | self.mark.start(mark_interval) |
447 |
looks good.