~savilerow-team/savilerow/rtm-custom-tools

« back to all changes in this revision

Viewing changes to click-sync.py

  • Committer: Chris Wayne
  • Date: 2014-09-23 00:36:57 UTC
  • Revision ID: chris.wayne@canonical.com-20140923003657-44hpbeluxo4ti7rg
Tools to create RTM custom tarball initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python2
 
2
 
 
3
from __future__ import print_function
 
4
 
 
5
from oauth import oauth
 
6
 
 
7
import argparse
 
8
import httplib2
 
9
import json
 
10
import os
 
11
import subprocess
 
12
import urllib
 
13
import logging
 
14
 
 
15
logging.basicConfig(level=logging.INFO)
 
16
log = logging.getLogger()
 
17
log.name = 'click-sync'
 
18
 
 
19
job_template = '%s/job/%s/lastSuccessfulBuild/api/json'
 
20
artifacts_template = '%s/job/%s/lastSuccessfulBuild/artifact/%s'
 
21
 
 
22
store_uri = 'https://search.apps.ubuntu.com/api/v1/package/%s'
 
23
 
 
24
click_packages = [
 
25
    ]
 
26
 
 
27
click_packages_staged = [
 
28
    'camera-app-click',
 
29
    ]
 
30
 
 
31
store_click_packages = [
 
32
    'com.canonical.payui',
 
33
    'com.ubuntu.calculator',
 
34
    'com.ubuntu.calendar',
 
35
    'com.ubuntu.camera',
 
36
    'com.ubuntu.clock',
 
37
    'com.ubuntu.dropping-letters',
 
38
    'com.ubuntu.filemanager',
 
39
    'com.ubuntu.gallery',
 
40
    'com.ubuntu.notes',
 
41
    'com.ubuntu.music',
 
42
    'com.ubuntu.reminders',
 
43
    'com.ubuntu.shorts',
 
44
    'com.ubuntu.sudoku',
 
45
    'com.ubuntu.terminal',
 
46
    'com.ubuntu.weather',
 
47
    'com.ubuntu.scopes.youtube',
 
48
    'com.ubuntu.developer.webapps.webapp-amazon',
 
49
    'com.ubuntu.developer.webapps.webapp-ebay',
 
50
    'com.ubuntu.developer.webapps.webapp-facebook',
 
51
    'com.ubuntu.developer.webapps.webapp-gmail',
 
52
    'com.ubuntu.developer.webapps.webapp-twitter',
 
53
    ]
 
54
 
 
55
 
 
56
class OAuthClient(object):
 
57
 
 
58
    @classmethod
 
59
    def credentials_from_file(cls, credentials_file):
 
60
        with open(credentials_file, 'r') as f:
 
61
            tokens = json.loads(f.read())
 
62
        return cls(**tokens)
 
63
 
 
64
    def __init__(self, consumer_key, consumer_secret,
 
65
                 token_key, token_secret):
 
66
        self.consumer = oauth.OAuthConsumer(key=consumer_key,
 
67
                                            secret=consumer_secret)
 
68
        self.access_token = oauth.OAuthToken(token_key, token_secret)
 
69
        self.signature_method = oauth.OAuthSignatureMethod_PLAINTEXT()
 
70
 
 
71
    def get_auth_headers(self, url):
 
72
        oauth_request = oauth.OAuthRequest.from_consumer_and_token(
 
73
            http_url=url,
 
74
            http_method="GET",
 
75
            oauth_consumer=self.consumer,
 
76
            token=self.access_token
 
77
            )
 
78
        oauth_request.sign_request(
 
79
            self.signature_method, self.consumer, self.access_token)
 
80
        return oauth_request.to_header()
 
81
 
 
82
 
 
83
def get_json_for_uri(click_uri):
 
84
    """
 
85
    Returns a json object for the latest successful job from the
 
86
    Jenkins uri.
 
87
    """
 
88
    log.debug(('Getting %s' % click_uri))
 
89
    json_request = urllib.urlopen(click_uri)
 
90
    if json_request.code != 200:
 
91
        raise RuntimeError('%s returned %s with %s' %
 
92
                           (click_uri, json_request.code, json_request.read()))
 
93
    json_content = json.loads(json_request.read())
 
94
    return json_content
 
95
 
 
96
 
 
97
def remove_if_previous(click_package, target_dir):
 
98
    """
 
99
    Locates click_package in target directory and removes it.
 
100
    """
 
101
    dir_contents = os.listdir(target_dir)
 
102
    click_package.split('_')[0]
 
103
    matches = filter(lambda x: click_package in x, dir_contents)
 
104
    for match in matches:
 
105
        target = os.path.join(target_dir, match)
 
106
        if os.path.exists(target):
 
107
            log.debug('Removing previous click package %s' % match)
 
108
            os.unlink(target)
 
109
 
 
110
 
 
111
def download(uri, target_file):
 
112
    """
 
113
    Downloads uri to target_file.
 
114
    """
 
115
    log.debug(('Downloading %s to %s' % (uri, target_file)))
 
116
    new_target_file = "%s.new" % target_file
 
117
    try:
 
118
        subprocess.check_call(['wget', '--quiet', uri, '-O', new_target_file])
 
119
    except subprocess.CalledProcessError:
 
120
        if os.path.exists(new_target_file):
 
121
            os.unlink(new_target_file)
 
122
        raise
 
123
    os.rename(new_target_file, target_file)
 
124
 
 
125
 
 
126
def get_store_apps(download_dir, auth=None):
 
127
    """
 
128
    Gets click apps from the store.
 
129
    """
 
130
    http_client = httplib2.Http()
 
131
    download_list = []
 
132
    for click in store_click_packages:
 
133
        json_content = get_json_for_uri(store_uri % click)
 
134
        click_file = json_content['download_url'].split('/')[-1]
 
135
        target_file = os.path.join(download_dir, click_file)
 
136
        download_url = json_content['download_url']
 
137
        if auth:
 
138
            auth_headers = auth.get_auth_headers(download_url)
 
139
            log.debug('auth_headers: %s' % auth_headers)
 
140
        else:
 
141
            auth_headers = None
 
142
            download_url += '?noauth=1'
 
143
            log.warn('Downloading with noauth')
 
144
        respr, content = http_client.request(
 
145
            download_url, "GET", headers=auth_headers)
 
146
        if respr['status'] != '200':
 
147
            raise EnvironmentError(respr)
 
148
        with open(target_file, 'w') as f:
 
149
            f.write(content)
 
150
        download_list.append(click_file)
 
151
    return download_list
 
152
 
 
153
 
 
154
def parse_arguments():
 
155
    parser = argparse.ArgumentParser(description='Click package sync tool')
 
156
    parser.add_argument('jenkins_url',
 
157
                        help='jenkins url to download click packages from.')
 
158
    parser.add_argument('download_dir',
 
159
                        help='''Path to store the downloaded click packages.
 
160
                                The path must exist''')
 
161
    parser.add_argument('--credentials-file', default=None, required=False,
 
162
                        help='''json dictionary with tokens for oauth.''')
 
163
    return parser.parse_args()
 
164
 
 
165
 
 
166
if __name__ == '__main__':
 
167
    args = parse_arguments()
 
168
    download_list = []
 
169
 
 
170
    # Jenkins part
 
171
    for click_package in click_packages:
 
172
        url = job_template % (args.jenkins_url, click_package)
 
173
        json_job = get_json_for_uri(url)
 
174
        click_package_uri = (artifacts_template %
 
175
                             (args.jenkins_url,
 
176
                              click_package,
 
177
                              json_job['artifacts'][0]['relativePath']))
 
178
        click_files = [x['fileName'] for x in json_job['artifacts']
 
179
                       if x['fileName'].endswith('.click')]
 
180
        for click_file in click_files:
 
181
            target_file = os.path.join(args.download_dir, click_file)
 
182
            remove_if_previous(click_file, args.download_dir)
 
183
            download(click_package_uri, target_file)
 
184
            download_list.append(click_file)
 
185
 
 
186
    # Store part
 
187
    auth = None
 
188
    if args.credentials_file:
 
189
        auth = OAuthClient.credentials_from_file(args.credentials_file)
 
190
    download_list = download_list + get_store_apps(args.download_dir, auth)
 
191
 
 
192
    click_list = os.path.join(args.download_dir, 'click_list')
 
193
    with open(click_list, 'w') as f:
 
194
        for i in download_list:
 
195
            f.write('%s\n' % i)