3
from __future__ import print_function
5
from oauth import oauth
15
logging.basicConfig(level=logging.INFO)
16
log = logging.getLogger()
17
log.name = 'click-sync'
19
job_template = '%s/job/%s/lastSuccessfulBuild/api/json'
20
artifacts_template = '%s/job/%s/lastSuccessfulBuild/artifact/%s'
22
store_uri = 'https://search.apps.ubuntu.com/api/v1/package/%s'
27
click_packages_staged = [
31
store_click_packages = [
32
'com.canonical.payui',
33
'com.ubuntu.calculator',
34
'com.ubuntu.calendar',
37
'com.ubuntu.dropping-letters',
38
'com.ubuntu.filemanager',
42
'com.ubuntu.reminders',
45
'com.ubuntu.terminal',
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',
56
class OAuthClient(object):
59
def credentials_from_file(cls, credentials_file):
60
with open(credentials_file, 'r') as f:
61
tokens = json.loads(f.read())
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()
71
def get_auth_headers(self, url):
72
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
75
oauth_consumer=self.consumer,
76
token=self.access_token
78
oauth_request.sign_request(
79
self.signature_method, self.consumer, self.access_token)
80
return oauth_request.to_header()
83
def get_json_for_uri(click_uri):
85
Returns a json object for the latest successful job from the
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())
97
def remove_if_previous(click_package, target_dir):
99
Locates click_package in target directory and removes it.
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)
111
def download(uri, target_file):
113
Downloads uri to target_file.
115
log.debug(('Downloading %s to %s' % (uri, target_file)))
116
new_target_file = "%s.new" % target_file
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)
123
os.rename(new_target_file, target_file)
126
def get_store_apps(download_dir, auth=None):
128
Gets click apps from the store.
130
http_client = httplib2.Http()
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']
138
auth_headers = auth.get_auth_headers(download_url)
139
log.debug('auth_headers: %s' % auth_headers)
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:
150
download_list.append(click_file)
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()
166
if __name__ == '__main__':
167
args = parse_arguments()
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 %
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)
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)
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: