1#!/usr/bin/env python
2
3# Copyright 2014 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7'''Publishes ChromeVox to the webstore.
8  Given an unpacked extension, compresses and sends to the Chrome webstore.
9
10  Releasing to the webstore should involve the following manual steps before
11      running this script:
12    1. clean the output directory.
13    2. make a release build.
14    3. run manual smoke tests.
15    4. run automated ChromeVox tests.
16'''
17
18import chromevox_webstore_util
19import json
20import optparse
21import os
22import sys
23import tempfile
24from zipfile import ZipFile
25
26# A list of files (or directories) to exclude from the webstore build.
27EXCLUDE_PATHS = [
28    'cvox2/background/',
29    'deps.js',
30    'manifest_guest.json',
31    'manifest_next.json',
32    'manifest_next_guest.json'
33    ]
34
35
36def CreateOptionParser():
37  parser = optparse.OptionParser(description=__doc__)
38  parser.usage = '%prog <extension_path> <output_path> <client_secret'
39  return parser
40
41def MakeManifestEdits(root, old, new_file):
42  '''Customize a manifest for the webstore.
43
44  Args:
45    root: The directory containing file.
46
47    old: A json file.
48
49    new_file: a temporary file to place the manifest in.
50
51  Returns:
52    File of the new manifest.
53  '''
54  with open(os.path.join(root, old)) as old_file:
55    new_contents = json.loads(old_file.read())
56    new_contents.pop('key', '')
57    new_file.file.write(json.dumps(new_contents))
58
59def RunInteractivePrompt(client_secret, output_path):
60  input = ''
61  while True:
62    print 'u upload'
63    print 'g get upload status'
64    print 't publish trusted tester'
65    print 'p publish public'
66    print 'q quit'
67    input = raw_input('Please select an option: ')
68    input = input.strip()
69    if input == 'g':
70      print ('Upload status: %s' %
71             chromevox_webstore_util.GetUploadStatus(client_secret).read())
72    elif input == 'u':
73      print ('Uploaded with status: %s' %
74             chromevox_webstore_util.PostUpload(output_path, client_secret))
75    elif input == 't':
76      print ('Published to trusted testers with status: %s' %
77             chromevox_webstore_util.PostPublishTrustedTesters(
78                 client_secret).read())
79    elif input == 'p':
80      print ('Published to public with status: %s' %
81             chromevox_webstore_util.PostPublish(client_secret).read())
82    elif input == 'q':
83      sys.exit()
84    else:
85      print 'Unrecognized option: %s' % input
86
87def main():
88  _, args = CreateOptionParser().parse_args()
89  if len(args) != 3:
90    print 'Expected exactly three arguments'
91    sys.exit(1)
92
93  extension_path = args[0]
94  output_path = args[1]
95  client_secret = args[2]
96
97  with ZipFile(output_path, 'w') as zip:
98    for root, dirs, files in os.walk(extension_path):
99      rel_path = os.path.join(os.path.relpath(root, extension_path), '')
100      if rel_path in EXCLUDE_PATHS:
101        continue
102
103      for extension_file in files:
104        if extension_file in EXCLUDE_PATHS:
105          continue
106        if extension_file == 'manifest.json':
107          new_file = tempfile.NamedTemporaryFile(mode='w+a', bufsize=0)
108          MakeManifestEdits(root, extension_file, new_file)
109          zip.write(
110              new_file.name, os.path.join(rel_path, extension_file))
111          continue
112
113        zip.write(os.path.join(root, extension_file),
114                  os.path.join(rel_path, extension_file))
115  print 'Created ChromeVox zip file in %s' % output_path
116  print 'Please run manual smoke tests before proceeding.'
117  RunInteractivePrompt(client_secret, output_path)
118
119
120if __name__ == '__main__':
121  main()
122