Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import csv | |
| 6 import optparse | |
| 7 import os | |
| 8 import shutil | |
| 9 import sys | |
| 10 import tempfile | |
| 11 import urllib2 | |
| 12 import zipfile | |
| 13 | |
| 14 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, | |
| 15 'telemetry')) | |
| 16 | |
| 17 from catapult_base import cloud_storage | |
| 18 from telemetry.core import exceptions | |
| 19 | |
| 20 # Remote target upload directory in cloud storage for extensions. | |
| 21 REMOTE_DIR = 'extension_set' | |
| 22 | |
| 23 # Target zip file. | |
| 24 ZIP_NAME = 'extensions.zip' | |
| 25 | |
| 26 def _DownloadCrxFromCws(ext_id, dst): | |
| 27 """Downloads CRX specified from Chrome Web Store. | |
| 28 | |
| 29 Retrieves CRX (Chrome extension file) specified by ext_id from Chrome Web | |
| 30 Store, into directory specified by dst. | |
|
nednguyen
2015/07/17 21:48:07
Does this CRX file have a fixed version?
sydli
2015/07/17 22:29:27
No, should it be? update_remote_extensions will no
nednguyen
2015/07/17 22:49:08
I see. In case someone runs "update_remote_extensi
sydli
2015/07/20 21:33:41
Done; not sure if this is exactly what you meant,
| |
| 31 | |
| 32 Args: | |
| 33 ext_id: id of extension to retrieve. | |
| 34 dst: directory to download CRX into | |
| 35 | |
| 36 Returns: | |
| 37 Returns local path to downloaded CRX. | |
| 38 If download fails, return None. | |
| 39 """ | |
| 40 dst_path = os.path.join(dst, '%s.crx' % ext_id) | |
| 41 cws_url = ('https://clients2.google.com/service/update2/crx?response=' | |
| 42 'redirect&prodversion=38.0&x=id%%3D%s%%26installsource%%3D' | |
| 43 'ondemand%%26uc' % ext_id) | |
| 44 response = urllib2.urlopen(cws_url) | |
| 45 if response.getcode() is not 200: | |
| 46 return None | |
| 47 with open(dst_path, 'w') as f: | |
| 48 f.write(response.read()) | |
| 49 return dst_path | |
| 50 | |
| 51 def _UpdateExtensionsInCloud(local_extensions_dir, extensions_csv, remote_dir): | |
| 52 """Updates set of extensions in Cloud Storage from a CSV of extension ids. | |
| 53 | |
| 54 From well-formatted CSV file containing some set of extensions | |
| 55 (extensions_csv), download them, compress into archive, and update | |
| 56 the remote extension archive under REMOTE_DIR in CHROME-PARTNER-TELEMETRY | |
| 57 bucket. This script expects 2nd column of CSV file to contain extension ids. | |
| 58 | |
| 59 Args: | |
| 60 local_extensions_dir: directory to download CRX files into. | |
| 61 extension_csv: CSV to pull extension_ids from. | |
| 62 remote_dir: remote directory to put extension archive in cloud storage. | |
| 63 | |
| 64 Raises: | |
| 65 Exception if a CRX download fails. | |
| 66 """ | |
| 67 # Download CRX to temp files and compress into archive | |
| 68 zip_path = os.path.join(local_extensions_dir, ZIP_NAME) | |
| 69 extension_zip = zipfile.ZipFile(zip_path, 'w') | |
| 70 with open(extensions_csv, 'rb') as csv_file: | |
| 71 reader = csv.reader(csv_file) | |
| 72 reader.next() # skip header line | |
| 73 for row in reader: | |
| 74 extension_id = row[1] | |
| 75 print 'Fetching extension %s...' % extension_id | |
| 76 crx_path = _DownloadCrxFromCws(extension_id, local_extensions_dir) | |
| 77 if crx_path is None: | |
| 78 raise exceptions.Error('\tCould not fetch %s.\n\n' | |
| 79 'If this extension dl consistently fails, ' | |
| 80 'remove this entry from %s.' | |
| 81 % (extension_id, extensions_csv)) | |
| 82 extension_zip.write(crx_path, arcname='%s.crx' % extension_id) | |
| 83 extension_zip.close() | |
| 84 print 'Uploading extensions to cloud...' | |
| 85 remote_zip_path = os.path.join(remote_dir, ZIP_NAME) | |
| 86 cloud_storage.Insert(cloud_storage.PARTNER_BUCKET, remote_zip_path, zip_path) | |
| 87 | |
| 88 def _GetCsvFromArgs(): | |
| 89 """Parse options to retrieve name of CSV file.""" | |
| 90 parser = optparse.OptionParser() | |
| 91 parser.add_option('-e', '--extension-csv', dest='extension_csv', | |
| 92 help='CSV of extensions to load.') | |
| 93 (options, _) = parser.parse_args() | |
| 94 if not options.extension_csv: | |
| 95 parser.error('Must specify --extension-csv option.') | |
| 96 return options.extension_csv | |
| 97 | |
| 98 def main(): | |
| 99 extension_csv = _GetCsvFromArgs() | |
| 100 local_extensions_dir = tempfile.mkdtemp() | |
| 101 try: | |
| 102 _UpdateExtensionsInCloud(local_extensions_dir, | |
| 103 extension_csv, REMOTE_DIR) | |
| 104 finally: | |
| 105 shutil.rmtree(local_extensions_dir) | |
| 106 | |
| 107 if __name__ == '__main__': | |
| 108 main() | |
| 109 | |
| OLD | NEW |