Merge lp:~nataliabidart/ubuntuone-client/fix-u1sync into lp:ubuntuone-client

Proposed by Natalia Bidart
Status: Merged
Approved by: dobey
Approved revision: 689
Merged at revision: 688
Proposed branch: lp:~nataliabidart/ubuntuone-client/fix-u1sync
Merge into: lp:ubuntuone-client
Diff against target: 239 lines (+18/-104)
2 files modified
ubuntuone/u1sync/client.py (+11/-82)
ubuntuone/u1sync/main.py (+7/-22)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-client/fix-u1sync
Reviewer Review Type Date Requested Status
Lucio Torre (community) Approve
Facundo Batista (community) Approve
Review via email: mp+35023@code.launchpad.net

Commit message

* Made u1sync client work from the command line. No more "authorize" option, only --oauth (LP: #634337).

To post a comment you must log in.
Revision history for this message
Facundo Batista (facundo) wrote :

Thanks!

review: Approve
Revision history for this message
Lucio Torre (lucio.torre) :
review: Approve
Revision history for this message
dobey (dobey) wrote :

Please leave this as needs review for now. There are some issues with launchpad, and setting this to Approve will denote the wrong revision number for merging.

I've reported https://bugs.edge.launchpad.net/launchpad/+bug/634451 and bugged the LP hackers to get it fixed. Hopefully it will be fixed very shortly and we can go back about our normal lives.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntuone/u1sync/client.py'
--- ubuntuone/u1sync/client.py 2010-06-23 15:31:32 +0000
+++ ubuntuone/u1sync/client.py 2010-09-10 02:20:59 +0000
@@ -28,8 +28,6 @@
28from Queue import Queue28from Queue import Queue
29from threading import Lock29from threading import Lock
30import zlib30import zlib
31import urlparse
32import ConfigParser
33from cStringIO import StringIO31from cStringIO import StringIO
3432
35from twisted.internet import reactor, defer33from twisted.internet import reactor, defer
@@ -37,12 +35,11 @@
37from ubuntuone.logger import LOGFOLDER35from ubuntuone.logger import LOGFOLDER
38from ubuntuone.storageprotocol.content_hash import crc3236from ubuntuone.storageprotocol.content_hash import crc32
39from ubuntuone.storageprotocol.context import get_ssl_context37from ubuntuone.storageprotocol.context import get_ssl_context
40from ubuntu_sso.config import get_config as get_oauth_config
41from ubuntu_sso.auth import AuthorisationClient
42from ubuntuone.u1sync.genericmerge import MergeNode38from ubuntuone.u1sync.genericmerge import MergeNode
43from ubuntuone.u1sync.utils import should_sync39from ubuntuone.u1sync.utils import should_sync
4440
45CONSUMER_KEY = "ubuntuone"41CONSUMER_KEY = "ubuntuone"
42CONSUMER_SECRET = "hammertime"
4643
47from oauth.oauth import OAuthConsumer44from oauth.oauth import OAuthConsumer
48from ubuntuone.storageprotocol.client import (45from ubuntuone.storageprotocol.client import (
@@ -177,9 +174,12 @@
177 """U1 storage client facade."""174 """U1 storage client facade."""
178 required_caps = frozenset(["no-content", "fix462230"])175 required_caps = frozenset(["no-content", "fix462230"])
179176
180 def __init__(self, realm, reactor=reactor):177 def __init__(self, realm=None, reactor=reactor):
181 """Create the instance."""178 """Create the instance.
182179
180 'realm' is no longer used, but is left as param for API compatibility.
181
182 """
183 self.reactor = reactor183 self.reactor = reactor
184 self.factory = SyncClientFactory(self)184 self.factory = SyncClientFactory(self)
185185
@@ -189,37 +189,8 @@
189 self._status_waiting = []189 self._status_waiting = []
190 self._active_waiters = set()190 self._active_waiters = set()
191191
192 self.realm = realm
193
194 oauth_config = get_oauth_config()
195 if oauth_config.has_section(realm):
196 config_section = realm
197 elif self.realm.startswith("http://localhost") and \
198 oauth_config.has_section("http://localhost"):
199 config_section = "http://localhost"
200 else:
201 config_section = "default"
202
203 @log_timing
204 def get_oauth_option(option):
205 """Retrieves an option from oauth config."""
206 try:
207 return oauth_config.get(config_section, option)
208 except ConfigParser.NoOptionError:
209 return oauth_config.get("default", option)
210
211 @log_timing
212 def get_oauth_url(option):
213 """Retrieves an absolutized URL from the OAuth config."""
214 suffix = get_oauth_option(option)
215 return urlparse.urljoin(realm, suffix)
216
217 self.consumer_key = CONSUMER_KEY192 self.consumer_key = CONSUMER_KEY
218 self.consumer_secret = get_oauth_option("consumer_secret")193 self.consumer_secret = CONSUMER_SECRET
219
220 self.request_token_url = get_oauth_url("request_token_url")
221 self.user_authorisation_url = get_oauth_url("user_authorisation_url")
222 self.access_token_url = get_oauth_url("access_token_url")
223194
224 def force_shutdown(self):195 def force_shutdown(self):
225 """Forces the client to shut itself down."""196 """Forces the client to shut itself down."""
@@ -256,49 +227,6 @@
256 self._active_waiters.remove(waiter)227 self._active_waiters.remove(waiter)
257228
258 @log_timing229 @log_timing
259 def obtain_oauth_token(self, create_token):
260 """Obtains an oauth token, optionally creating one if requried."""
261 token_result = self._get_waiter()
262
263 @log_timing
264 def have_token(token):
265 """When a token is available."""
266 token_result.wake(token)
267
268 @log_timing
269 def no_token():
270 """When no token is available."""
271 token_result.wake(None)
272
273 oauth_client = AuthorisationClient(realm=self.realm,
274 request_token_url=
275 self.request_token_url,
276 user_authorisation_url=
277 self.user_authorisation_url,
278 access_token_url=
279 self.access_token_url,
280 consumer_key=self.consumer_key,
281 consumer_secret=
282 self.consumer_secret,
283 callback_parent=have_token,
284 callback_denied=no_token,
285 do_login=create_token)
286
287
288 @log_timing
289 def _obtain_token():
290 """Obtains or creates a token."""
291 if create_token:
292 oauth_client.clear_token()
293 oauth_client.ensure_access_token()
294
295 self.reactor.callFromThread(_obtain_token)
296 token = self._wait(token_result)
297 if token is None:
298 raise AuthenticationError("Unable to obtain OAuth token.")
299 return token
300
301 @log_timing
302 def _change_status(self, status, reason=None):230 def _change_status(self, status, reason=None):
303 """Changes the client status. Usually called from the reactor231 """Changes the client status. Usually called from the reactor
304 thread.232 thread.
@@ -412,10 +340,11 @@
412 self._await_status_not("connecting", "connected", "authenticated")340 self._await_status_not("connecting", "connected", "authenticated")
413341
414 @log_timing342 @log_timing
415 def oauth_from_token(self, token):343 def oauth_from_token(self, token, consumer=None):
416 """Perform OAuth authorisation using an existing token."""344 """Perform OAuth authorisation using an existing token."""
417345
418 consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)346 if consumer is None:
347 consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)
419348
420 def _auth_successful(value):349 def _auth_successful(value):
421 """Callback for successful auth. Changes status to350 """Callback for successful auth. Changes status to
422351
=== modified file 'ubuntuone/u1sync/main.py'
--- ubuntuone/u1sync/main.py 2010-08-16 22:14:19 +0000
+++ ubuntuone/u1sync/main.py 2010-09-10 02:20:59 +0000
@@ -282,7 +282,6 @@
282def do_main(argv):282def do_main(argv):
283 """The main user-facing portion of the script."""283 """The main user-facing portion of the script."""
284 usage = "Usage: %prog [options] [DIRECTORY]\n" \284 usage = "Usage: %prog [options] [DIRECTORY]\n" \
285 " %prog --authorize [options]\n" \
286 " %prog --list-shares [options]\n" \285 " %prog --list-shares [options]\n" \
287 " %prog --init [--share=SHARE_UUID] [options] DIRECTORY\n" \286 " %prog --init [--share=SHARE_UUID] [options] DIRECTORY\n" \
288 " %prog --diff [--share=SHARE_UUID] [options] DIRECTORY"287 " %prog --diff [--share=SHARE_UUID] [options] DIRECTORY"
@@ -294,9 +293,7 @@
294 default='fs-1.one.ubuntu.com',293 default='fs-1.one.ubuntu.com',
295 help="The server address")294 help="The server address")
296 parser.add_option("--oauth", dest="oauth", metavar="KEY:SECRET",295 parser.add_option("--oauth", dest="oauth", metavar="KEY:SECRET",
297 default=None,296 help="Explicitly provide OAuth credentials")
298 help="Explicitly provide OAuth credentials "
299 "(default is to query keyring)")
300 action_list = ", ".join(sorted(MERGE_ACTIONS.keys()))297 action_list = ", ".join(sorted(MERGE_ACTIONS.keys()))
301 parser.add_option("--action", dest="action", metavar="ACTION",298 parser.add_option("--action", dest="action", metavar="ACTION",
302 default=None,299 default=None,
@@ -307,9 +304,6 @@
307 "making changes")304 "making changes")
308 parser.add_option("--quiet", action="store_true", dest="quiet",305 parser.add_option("--quiet", action="store_true", dest="quiet",
309 default=False, help="Produces less output")306 default=False, help="Produces less output")
310 parser.add_option("--authorize", action="store_const", dest="mode",
311 const="authorize",
312 help="Authorize this machine")
313 parser.add_option("--list-shares", action="store_const", dest="mode",307 parser.add_option("--list-shares", action="store_const", dest="mode",
314 const="list-shares", default="sync",308 const="list-shares", default="sync",
315 help="List available shares")309 help="List available shares")
@@ -351,17 +345,14 @@
351 else:345 else:
352 directory = args[0]346 directory = args[0]
353 if options.mode == "init" or options.mode == "list-shares" or \347 if options.mode == "init" or options.mode == "list-shares" or \
354 options.mode == "diff" or options.mode == "authorize":348 options.mode == "diff":
355 if options.action is not None:349 if options.action is not None:
356 parser.error("--%s does not take the --action parameter" % \350 parser.error("--%s does not take the --action parameter" % \
357 options.mode)351 options.mode)
358 if options.dry_run:352 if options.dry_run:
359 parser.error("--%s does not take the --dry-run parameter" % \353 parser.error("--%s does not take the --dry-run parameter" % \
360 options.mode)354 options.mode)
361 if options.mode == "authorize":355 if options.mode == "list-shares":
362 if options.oauth is not None:
363 parser.error("--authorize does not take the --oauth parameter")
364 if options.mode == "list-shares" or options.mode == "authorize":
365 if len(args) != 0:356 if len(args) != 0:
366 parser.error("--list-shares does not take a directory")357 parser.error("--list-shares does not take a directory")
367 if options.mode != "init" and options.mode != "diff":358 if options.mode != "init" and options.mode != "diff":
@@ -376,8 +367,9 @@
376 options.action = DEFAULT_MERGE_ACTION367 options.action = DEFAULT_MERGE_ACTION
377368
378369
370 passed_token = None
379 if options.oauth is None:371 if options.oauth is None:
380 passed_token = None372 parser.error("--oauth is required")
381 else:373 else:
382 try:374 try:
383 (key, secret) = options.oauth.split(':', 2)375 (key, secret) = options.oauth.split(':', 2)
@@ -395,18 +387,14 @@
395 else:387 else:
396 share_spec = None388 share_spec = None
397389
398 client = Client(realm=options.realm, reactor=reactor)390 client = Client(reactor=reactor)
399391
400 signal.signal(signal.SIGINT, lambda s, f: client.force_shutdown())392 signal.signal(signal.SIGINT, lambda s, f: client.force_shutdown())
401 signal.signal(signal.SIGTERM, lambda s, f: client.force_shutdown())393 signal.signal(signal.SIGTERM, lambda s, f: client.force_shutdown())
402394
403 def run_client():395 def run_client():
404 """Run the blocking client."""396 """Run the blocking client."""
405 if passed_token is None:397 token = passed_token
406 should_create_token = (options.mode == "authorize")
407 token = client.obtain_oauth_token(create_token=should_create_token)
408 else:
409 token = passed_token
410398
411 client.connect_ssl(options.host, int(options.port), options.no_ssl_verify)399 client.connect_ssl(options.host, int(options.port), options.no_ssl_verify)
412400
@@ -429,9 +417,6 @@
429 directory=directory,417 directory=directory,
430 quiet=options.quiet, subtree_path=options.subtree,418 quiet=options.quiet, subtree_path=options.subtree,
431 ignore_symlinks=False)419 ignore_symlinks=False)
432 elif options.mode == "authorize":
433 if not options.quiet:
434 print "Authorized."
435 finally:420 finally:
436 client.disconnect()421 client.disconnect()
437422

Subscribers

People subscribed via source and target branches