~ubuntu-branches/ubuntu/lucid/desktopcouch/lucid-proposed

« back to all changes in this revision

Viewing changes to desktopcouch/replication_services/ubuntuone.py

  • Committer: James Westby
  • Date: 2009-10-14 13:43:23 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@canonical.com-20091014134323-yvov1mrx9xvs1i01
Merging shared upstream rev into target branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import hashlib
2
 
from oauth import oauth
3
 
import logging
4
 
import httplib2
5
 
import simplejson
6
 
import gnomekeyring
7
 
 
8
 
name = "Ubuntu One"
9
 
description = "The Ubuntu One cloud service"
10
 
 
11
 
oauth_consumer_key = "ubuntuone"
12
 
oauth_consumer_secret = "hammertime"
13
 
 
14
 
def is_active():
15
 
    """Can we deliver information?"""
16
 
    return get_oauth_data() is not None
17
 
 
18
 
oauth_data = None
19
 
def get_oauth_data():
20
 
    """Information needed to replicate to a server."""
21
 
    global oauth_data
22
 
    if oauth_data is not None:
23
 
        return oauth_data
24
 
 
25
 
    try:
26
 
        import gnomekeyring
27
 
        matches = gnomekeyring.find_items_sync(
28
 
            gnomekeyring.ITEM_GENERIC_SECRET,
29
 
            {'ubuntuone-realm': "https://ubuntuone.com",
30
 
             'oauth-consumer-key': oauth_consumer_key})
31
 
        if matches:
32
 
            # parse "a=b&c=d" to {"a":"b","c":"d"}
33
 
            kv_list = [x.split("=", 1) for x in matches[0].secret.split("&")]
34
 
            keys, values = zip(*kv_list)
35
 
            keys = [k.replace("oauth_", "") for k in keys]
36
 
            oauth_data = dict(zip(keys, values))
37
 
            oauth_data.update({
38
 
                "consumer_key": oauth_consumer_key,
39
 
                "consumer_secret": oauth_consumer_secret,
40
 
            })
41
 
            return oauth_data
42
 
    except ImportError, e:
43
 
        logging.info("Can't replicate to Ubuntu One cloud without credentials."
44
 
                " %s", e)
45
 
    except gnomekeyring.NoMatchError:
46
 
        logging.info("This machine hasn't authorized itself to Ubuntu One; "
47
 
                "replication to the cloud isn't possible until it has.  See "
48
 
                "'ubuntuone-client-applet'.")
49
 
    except gnomekeyring.NoKeyringDaemonError:
50
 
        logging.error("No keyring daemon found in this session, so we have "
51
 
                "no access to Ubuntu One data.")
52
 
 
53
 
def get_oauth_token(consumer):
54
 
    """Get the token from the keyring"""
55
 
    import gobject
56
 
    gobject.set_application_name("desktopcouch replication to Ubuntu One")
57
 
    try:
58
 
        items = gnomekeyring.find_items_sync(
59
 
            gnomekeyring.ITEM_GENERIC_SECRET,
60
 
            {'ubuntuone-realm': "https://one.ubuntu.com",
61
 
             'oauth-consumer-key': consumer.key})
62
 
    except gnomekeyring.NoMatchError:
63
 
        logging.info("No o.u.c key.  Maybe there's uo.c key?")
64
 
        items = gnomekeyring.find_items_sync(
65
 
            gnomekeyring.ITEM_GENERIC_SECRET,
66
 
            {'ubuntuone-realm': "https://ubuntuone.com",
67
 
             'oauth-consumer-key': consumer.key})
68
 
    if len(items):
69
 
        return oauth.OAuthToken.from_string(items[0].secret)
70
 
 
71
 
def get_oauth_request_header(consumer, access_token, http_url):
72
 
    """Get an oauth request header given the token and the url"""
73
 
    signature_method = oauth.OAuthSignatureMethod_PLAINTEXT()
74
 
    assert http_url.startswith("https")
75
 
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
76
 
        http_url=http_url,
77
 
        http_method="GET",
78
 
        oauth_consumer=consumer,
79
 
        token=access_token)
80
 
    oauth_request.sign_request(signature_method, consumer, access_token)
81
 
    return oauth_request.to_header()
82
 
 
83
 
 
84
 
class PrefixGetter():
85
 
    def __init__(self):
86
 
        self.str = None
87
 
        self.oauth_header = None
88
 
 
89
 
    def __str__(self):
90
 
        if self.str is not None:
91
 
            return self.str
92
 
 
93
 
        url = "https://one.ubuntu.com/api/account/"
94
 
        if self.oauth_header is None:
95
 
            consumer = oauth.OAuthConsumer(oauth_consumer_key,
96
 
                    oauth_consumer_secret)
97
 
            try:
98
 
                access_token = get_oauth_token(consumer)
99
 
            except gnomekeyring.NoKeyringDaemonError:
100
 
                logging.info("No keyring daemon is running for this session.")
101
 
                raise ValueError("No keyring access")
102
 
            if not access_token:
103
 
                logging.info("Could not get access token from keyring")
104
 
                raise ValueError("No keyring access")
105
 
            self.oauth_header = get_oauth_request_header(consumer, access_token, url)
106
 
 
107
 
        client = httplib2.Http()
108
 
        resp, content = client.request(url, "GET", headers=self.oauth_header)
109
 
        if resp['status'] == "200":
110
 
            document = simplejson.loads(content)
111
 
            if "couchdb_root" not in document:
112
 
                raise ValueError("couchdb_root not found in %s" % (document,))
113
 
            self.str = document["couchdb_root"]
114
 
        else:
115
 
            logging.error("Couldn't talk to %r.  Got HTTP %s", url, resp['status'])
116
 
            raise ValueError("HTTP %s for %r" % (resp['status'], url))
117
 
 
118
 
        return self.str
119
 
 
120
 
# Access to this as a string fires off functions.
121
 
db_name_prefix = PrefixGetter()
122
 
 
123
 
if __name__ == "__main__":
124
 
    logging.basicConfig(level=logging.DEBUG, format="%(message)s")
125
 
    print str(db_name_prefix)